Why does Ember.js rock?
In response to this blog post about why Angular.js rocks, I thought I’d write something similar about Ember.js.
Ember.js is a MVC (Model – View – Controller) JavaScript framework which is maintained by the Ember Core Team (including Tom Dale, Yehuda Katz, and others). It helps developers create ambitious single-page web applications that don’t sacrifice what makes the web great: URI semantics, RESTful architecture, and the write-once, run-anywhere trio of HTML, CSS, and JavaScript.
I could spend all day writing about why you should try Ember.js, but it’s probably better if I let it speak for itself.
Data binding
As you can see in the above example, Ember.js does support data binding. What we type into the input is bound to name
, as is the text after “Echo: ”. When you change the text, in one place, it automatically updates everywhere.
But how? Ember.js uses Handlebars for two-way data binding. Templates written in handlebars get and set data from their controller (which will be automatically generated with smart defaults if you don’t write it yourself, as it was here). Every time we type something in our input, the name
property of our controller is updated. Then, automatically, the template is updated because the bound data changed.
Alright, that was’t hard. Let’s see a more complex example.
This time, we explicitely generate our ApplicationController
instead of letting Ember.js generate it for us. In doing this, we set its properties, which are immediately available in the Handlebars template. Here, we’ve set the string message
to World
by default, while still binding it to the input and the text.
I’m sure you’re wondering if we can bind functions as well as primitives. Yes we can, using a mechanism called “Computed Properties”.
If you look at the ApplicationController
, you’ll notice that the shout
property is a function with the .property()
method called on it. This means that any time the property or properties you name in the .property()
method changes, the function will be run again, and the template will be updated. In addition, the Handlebars template contains the {{#if}}
helper, which tests for truthiness. Any time the value changes, Ember updates the DOM automatically.
Notice that the template does not care that the {{shout}}
binding is a function. This is by design, as the Uniform Access Principle states that “All services offered by a module should be available through a uniform notation, which does not betray whether they are implemented through storage or through computation.” Basically, you never have to re-write the template if you decide a primitive needs to be a computed property.
Components
A component is a way to teach HTML new tricks. Instead of being limited to the tags and functionality set forth by the W3C, you can invent your own elements. Ember.js has embraced this upcoming technology using Handlebars.
For example, instead of having this:
<div class="pie-chart"></div>
<script type="text/javascript">
$('.pie-chart').pieChart({
width: 640,
height: 480,
data: '1,2,3'
});
</script>
We could have this:
{{pie-chart width="640" height="480" data="1,2,3"}}
As an example, I’ve created and used hCard component below.
We defined our component by opening a new <script type="text/x-handlebars">
, and setting its template name (via the data-template-name
attribute) to be components/NAME
. Note that the web components (and Ember components) specification requires the name to have a dash in it, to separate it from existing HTML tags.
Components cannot see properties from the context they are called in. Instead, you must pass what you want the component to have access to into the component explicitely.
Handlebars Helpers
Imagine that we need to show somebody the cost of goods in their shopping cart.
Wouldn’t it be nice if we could format the total to look like money instead of just a bare number? We can!
Using the Accounting.js library, we wrote a custom Handlebars helper, money
, that will format a number to look like money. We can even pass in options to our helper.
Much, Much More
I’ve only scratched the surface here. For more information, feel free to peruse the wonderful Ember.js Guides. In particular, check out routing—tying the URL to application state. And if you really want to see the power of the Ember.js ecosystem, take a look at the (beta version of) Ember Data, an ORM for RESTful JSON APIs.