Show HN: Espresso.js – React Meets Backbone for a Minimal MVC
github.com
github.com
I actually use backbone and react right now and love it. I also thought flux was too much, so I'm very interested in a framework like this.
- A small library that you can read and hack easily
- No templates or HTML/JSX in your JavaScript
- Models & Collections are small wrappers around Objects & Arrays
- Declarative DOM representation provides a simple binding between views and models (optional)
- One-directional data flow
- Child components are managed automatically (no zombie views)
- Proper Collection.set performs a smart update without relying on sorting
- Built-in List component for displaying a list of models
This is very nice. I just have a few questions:
- is it possible to reuse markup from one place in another without copy-paste? (e.g. let's say I have a pagination control that I want to display both above below a table)
- how would you hook a third party library (e.g. let's say I need to use select2.js or pikaday.js)?
- is it possible to render things on the fly? (e.g. asynchronous modules) or does all of the HTML need to be on the page on page load?
sure, you can just place the markup in a hidden div and clone the node. or you can pass a string as the view name:
new Controller({ view: 'node-id' })
and the framework will do that for you: document.getElementById('node-id').cloneNode(true) and cache the node as well
we typically have a hidden div which contains all re-usable nodes that the app needs
> how would you hook a third party library
you can do anything you want in the init() method, just like backbone. this.view is the view node, and you also have access to this.ref[node-name]. you're not forced to user the render sugar the framework provides at all, eg the List class doesn't use it and updates the DOM imperatively.
> is it possible to render things on the fly
you can always fetch html from the server and do createElement() to generate a node from that, or inject the html/template into the page body. if you prefer to have html templates separate, you can just have your build script inject the templates into the body which makes the app much faster anyway in my experience.
- Basic model classes: Model and Collection similar to Backbone, but much simplified (no REST-API stuff, validations etc, it's basically just that events are fired when data is changed)
- There are no templates, all or most of the markup is already present on the page
- The Controller class is attached to a DOM element. Specific nodes (called 'refs' as in React) inside this element are denoted by the "data-ref" attribute. These are collected by the controller during init phase and then their state is managed via the render() method.
- there's a special List controller which can be connected to a Collection. It manages a list of sub-Controllers (each attached to an item in the Collection)
I like the simplicity. It's very similar to what I'm using lately for smaller projects.
- the render() method provides a way to declare what the DOM looks like (React-style) OR manipulate the DOM imperatively (Backbone style)
This helps the Flux one-directional data flow, which you can see in the ToDo example. Controller's model is actually its internal state by default, so all data mutation must go through the main data store.
Thank you so much for boiling it down to the key points, I've been struggling to explain the details clearly. Really the best way to understand what's going on is to read the ToDo app as it's only 100 lines.
We are using this for PhoneGap and node-webkit apps, it's a perfect for for mobiles where you need fine-grained control over memory and performance, and you know the runtime you're developing against (webkit) so there isn't a goal to get this running across every browser like React or Backbone.
- no need to diff the whole DOM tree
- no need to write JSX, you can simply use DOM nodes
the render() method still gives you most of the niceties of React, ie a declarative view of your DOM, without the nasty inclusion of HTML inside your JS controllers.
PS ToDoMVC performance benchmark shows the to-do app to be about 3-4x faster than React.
Moreover it gives you the option between declaratively specifying the DOM to imperatively manipulating it when you need to for performance reasons.
It's a tiny library and the approach is much more efficient than diffing the virtual DOM for the entire page, so I'm pretty confident that results would actually be even better in larger apps.
I prefer to do this:
render: function() { return { view: { classList: { editing: this.model.editing, completed: this.model.done } } } }
Compared to outputting the entire HTML for the component in render().
https://github.com/flatiron/director
Thanks, would be happy to accept contributions!
Is it just React the pattern (without the component part)?
https://cdn.rawgit.com/techlayer/espresso.js/master/docs/ind...
Would be nice if docs were higher up on the README though
MVP diagram: http://lostechies.com/derickbailey/files/2011/12/NewImage2.p...
Why Backbone is not MVC: http://lostechies.com/derickbailey/2011/12/23/backbone-js-is...
Having said that, I much prefer Backbones presenter idiom over MVC.
Now that I've looked at it a bit more, I have to echo the other commenter who asked about routing, particularly since the view markup is statically on the page. Perhaps I'm missing something?