What’s New in Ember 2.0?

Lamin Sanneh
Share


This article was peer reviewed by Stephan Max. Thanks to all of SitePoint’s peer reviewers for making SitePoint content the best it can be!

Ember is an JavaScript framework, based on the model-view-controller (MVC) pattern and used for creating single page applications. Recently, version 2.0 of the framework was released under the motto “Stability without Stagnation”. What this means is that Ember 2.0 didn’t ship with any new features, as those features intended for the 2.0 release (such as the Glimmer rendering engine) were already present in previous versions.

Ember 2.0 also removes many of the older APIs which had been deprecated in the 1.x versions. This means that if you can create an Ember 1.13 app which is free from deprecation warnings, the upgrade to 2.0 will be seamless. This is in stark contrast to the furor surrounding last year’s Angular 2.0 announcement.

The features intended for Ember 2.0 have been termed “precursor features” by the Ember team. So, for the rest of this article, I will be highlighting the major precursor features and how to use them. We will also examine some of the features intended for future releases.

If you would like to follow along, you’ll need to create an Ember project using the latest version of the framework. Show me how.

Ember is installed using npm. For a tutorial on npm, you can see here.

npm install -g ember-cli

At the time of writing this will pull in version 1.13

ember -v
=> version: 1.13.8

Next, create a new Ember app:

ember new hello-world

Navigate to that directory and edit the bower.json file to include the latest version of the Ember and ember-data

{
  "name": "hello-world",
  "dependencies": {
    "ember": "^2.0.0",
    "ember-data": "^2.0.0",
    ...
  }
}

Back in the terminal run:

bower install

Bower might prompt you for a version resolution for Ember. Select the 2.x version from the list provided and prefix it with an exclamation mark to persist the resolution to bower.json.

Next start Ember CLI’s development server:

ember server

Finally navigate to http://localhost:4200/ and check the version your browser’s console.

Precursor Features for Ember 2.0

Views

Views have been deprecated in favor of components. Consisting of two parts (a JavaScript component file and a Handlebars template), components are isolated by design and are better suited to reuse throughout your application (unlike views). A compatibility addon is available which will be maintained by the Ember team until version 2.6 of Ember. This is to help transition apps making heavy use of views to the latest Ember. Compatibility of this addon with Ember will stop at version 2.4. When building new Ember applications, developers should favor components over views.

ArrayController and ObjectController

ArrayController and ObjectController have been deprecated in favor of the generic Controller class. This is because they created some unnecessary confusion among developers and there was ambiguity about which controller type is generated by Ember if none is specified. With this deprecation, there will only be one type of controller.

To make this transition, change code which looks like this:

exports default Ember.ObjectController.extend({

or:

exports default Ember.ArrayController.extend({

to:

exports default Ember.Controller.extend({

A controller addon is also supported until Ember 2.6 to help transition apps.

Attribute Bindings

In past, the {{bind-attr}} helper was used to bind properties to DOM attributes. With Ember 2.0, you no longer need this helper. Instead of doing something like:

<a {{bind-attr href=location }} >Link Text</a>

You can now do something like this instead, which is much nicer and clearer

<a href={{location}} >Link Text</a>

Class Bindings

Binding classes to properties is simpler now, with the deprecation of the {{bind-attr}} helper. For example, instead of doing this

<div {{bind-attr class="isVisible"}} ></div>

You can now do this

<div class='{{if isVisible "is-visible" }}' ></div>

View and Controller Options on the Each Helper

The following properties itemView, itemViewClass, tagName, emptyView, emptyViewClass and itemController have been deprecated. These were options you could set when using the {{each}} helper. This deprecation is as a result of moving away from views and controllers towards components.

Suffice to say that components offer all the functionalities provided by these options. For example:

{{each view.comments itemController="comment"
                     itemView="commentView"
                     emptyView="noCommentsView"
                     tagName="ul"}}

becomes:

<ul>
  {{#each comments as |comment|}}
    {{post-comment comment=comment}}
  {{else}}
    {{no-comments}}
  {{/each}}
</ul>

Read more about this change.

Block Params

Block params have been introduced. This helps with uniformity and familiarity when using several handlebars helpers. For example when using the {{each}} helper, this code

{{#each person in people}}

now becomes

{{#each people as |person| }}

As for the {{with}} helper, this code

{{#with teacher as person}}

now becomes

{{#with teacher as |person| }}

Read more about this change

Controller Needs

The needs property for controllers is gone. This used to enable a controller to have access to another controller. You can now set the controller name as a property with its value injected. So this code

exports default Ember.Controller.extend({
  needs: ['application']
})

changes to:

exports default Ember.Controller.extend({
  application:  Ember.inject.controller()
})

You can now access the injected controller as application. This is shorter compared to the longer form controllers.application we used to have.

Observer Arguments Ordering

Observer arguments will now be in reverse order. The function used to be the first argument, followed by the dependent properties. Now we will have the function as the last argument instead of being first. So in essence this code

Ember.observer(function(){

}, 'someProperty1', 'someProperty2')

becomes

Ember.observer('someProperty1', 'someProperty2', function(){

})

IE8 Support

Support for Internet Explorer 8 has been dropped in Ember 2.0. From now on, only Internet Explorer 9 and above will be supported. There was even talk of dropping support for IE9, but after considerable debate, it was decided that the benefits of dropping IE9 in Ember 2.0 were not as strong.

Canary Features to Expect in Post Ember 2.0

These are some of the feature to expected when newer versions of Ember ship. For now, they are experimental and are only found in the canary build. To use them, you need to opt-in using the FEATURES property found in the Ember config file. A list of available features can be found here.

Angle-Bracket Components

An angle bracket syntax for components has been implemented. This makes it possible to invoke components in the same style as regular HTML elements. So you can change the following code from

{{#my-component}}{{/my-component}}

to:

<my-component></my-component>

The old syntax will still work alongside the new one for the time being so as to give developers of existing applications enough time to upgrade. In addition to the cleaner syntax angle-bracket components will introduce a default one-way data flow (which you maybe know from React) and provide an opt-in for two-way data flow.

One-Way Data Flow and the Mut Keyword

In previous versions of Ember, component properties used to be bound two ways. What this means is that the property of a component as well as its data source are both mutable. In Ember 2.0, component properties are now immutable by default. This behavior is a consequence of using the new angle-bracket syntax for components. For example in the code below using the old method to invoke a component.

{{#my-component firstName=model.name }}{{/my-component}}

The firstName property is bound to the name property of the model. When the value of the name property changes, the change is reflected in the firstName property. Likewise, we could change the firstName property and the change is reflected back in the name property of the model.

With the new syntax (as shown below) we can only change the value for the name property. We cannot change the value for the firstName property, as it is read-only.

<my-component firstName=model.name ></my-component>

There is however, a new mut keyword to circumvent this default behavior.

<my-component firstName={{mut model.name}} ></my-component>

This keyword makes the firstName property mutable by giving it two properties. First, a function called update which you can use to set the value of the property like so:

this.attrs.firstName.update("newFirstNameValue");

Second, a property called value. This holds the actual value of the property and is accessible like so

this.attrs.firstName.value;

The Attrs Property in Components

Another feature introduced by the new angle-bracket components is the attr property for components. Any property passed during invocation will not be directly present on the component, but rather in a component property called attr. So for example, when we invoke this component:

<my-component property1="somevalue" property2="someothervalue" >
</my-component>

In the past you could get access to the two properties like this.

this.get('property1')
this.get('property2')

but with the new syntax you have to access them like so

this.attrs.property1
this.attrs.property2

React-style Fast Re-Render

In previous versions of Ember, re-rendering a component used to be a computationally expensive operation. Ember used to tear down the whole DOM for the component and rebuild it from scratch. In the new engine called Glimmer, the rerender function is much smarter now. It only rebuilds the part of the DOM that needs to change. This allows for faster and more efficient re-renders.

Conclusion

Ember 2.0 is definitely a step in the right direction. There is a focus on uniformity and adhering to web standards which make Ember a stronger contender as a JavaScript framework to pick for your next new project. Let us know your thoughts on these new exciting features in the comments below.

And, for those of you wishing to dig into this more, I recommend watching the EmberConf2015 opening Keynote, by Tom Dale & Yehuda Katz, about everything that has happened on the way to Ember 2.0. Enjoy!