Since the previous release 0.9.5 and the current release 0.9.6 many changes have been made. Besides the many bug fixes, added documentation and speed improvements also some new features have been added. This blog post will cover some of them. The complete changelog is listed in ember.js/CHANGELOG.

It is now possible to define aliases for attributeBindings and define static class names, as already mentioned by Gordon Hempton in the excellent Eight Ember.js Gotchas With Workarounds blog post.

Use case for attribute bindings and static classes 1 2 3 4 5 6 7 8 9 10 Ember . View . create ({ template : Ember . Handlebars . compile ( '<div {{bindAttr class="boolAttr stringAttr isDisabled:disabled :staticClass"}}/>' ), boolAttr : true , stringAttr : 'helloWorld' , isDisabled : true , myThemeAttr : 'blue' , attributeBindings : 'myThemeAttr:data-theme' . w () }). append ();

So the view is rendered as follows:

1 2 3 <div data-theme= "blue" class= "ember-view" > <div class= "bool-attr helloWorld disabled staticClass" ></div> </div>

Where the following rules apply:

if the property is true and no alias has been specified, the dasherized property name is added ( boolAttr in the example above)

and no alias has been specified, the dasherized property name is added ( in the example above) if the property is true and an alias has been specified, the alias is used ( isDisabled:disabled in the example above)

and an alias has been specified, the alias is used ( in the example above) if the property is a String the value is added ( stringAttr in the example above)

the value is added ( in the example above) if the property is a String and an alias has been specified, the alias is used for the attribute name and the value is added ( myThemeAttr in the example above)

and an alias has been specified, the alias is used for the attribute name and the value is added ( in the example above) a static property is always added ( :staticClass in the example above)

It’s now possible to get a value from an object and additionally specifiy a default value which shall be returned when the object does not have a value for the specific property. The function itself is available on the Ember namespace via Ember.getWithDefault and is also aliased to Ember.Observable mixin so it’s available on Ember.Object ’s.

Use case for Ember.getWithDefault 1 2 3 4 5 6 7 var myObj = Ember . Object . create ({ name : 'Sepp' }); Ember . getWithDefault ( myObj , 'name' , 'Unknown' ); // Sepp myObj . getWithDefault ( 'name' , 'Unknown' ); // Sepp myObj . getWithDefault ( 'score' , 100 ); // 100

Ember.Map

Since 0.9.6 there is a new class Ember.Map available. As the documentation states, the keys can be any JavaScript object.

Use case for Ember.Map 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 var map = Ember . Map . create (); var tobias = Ember . Object . create ({ name : 'Tobias' }); var lindsay = Ember . Object . create ({ name : 'Lindsay' }); map . set ( lindsay , 'Fünke' ); map . set ( tobias , 'Fünke' ); map . set ( 'Maeby' , 'Fünke' ); map . forEach ( function ( key , value ) { console . log ( key , value ); }); map . get ( tobias ); // 'Fünke' map . has ( lindsay ); // true map . has ( 'Maeby' ); // true map . remove ( lindsay ); map . has ( lindsay ); // false

With the Ember.Evented mixin it’s possible to add and remove listeners for custom events.

Use case for Ember.Evented 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 var obj = Ember . Object . create ( Ember . Evented , { init : function () { this . _super (); this . on ( 'eventA' , this , 'eventAOccured' ); }, eventAOccured : function ( param ) { console . log ( 'eventA occured' ); } }); var targetObj = Ember . Object . create ({ eventBOccured : function ( first , second ) { console . log ( 'eventB occured' ); } }); obj . on ( 'eventB' , targetObj , 'eventBOccured' ); obj . fire ( 'eventA' , 'hello' ); // eventAOccured on obj is invoked with 'hello' as param obj . fire ( 'eventB' , 1 , 2 ); // eventBOccured on targetObj is invoked with 1 and 2 as parameters obj . off ( 'eventB' , targetObj , 'eventBOccured' ); // unregister event listener obj . fire ( 'eventB' ); // nothing is invoked since no listener is registered for this event

In the previous version the action helper invoked an action and passed 3 arguments: view , event and context .

Action helper in Ember.js v0.9.5 1 2 3 4 App . ItemView = Ember . View . extend ({ removeItem : function ( view , event , context ) { } })

Since 0.9.6 only one argument event is passed which has the view and context stashed as properties on it.

Action helper in Ember.js v0.9.6 1 2 3 4 5 6 App . ItemView = Ember . View . extend ({ removeItem : function ( event ) { var view = event . view ; var context = event . context ; } })

The text controls of Ember.js learned additional properties which can be bound. These are maxlength of Ember.TextSupport , size of Ember.TextField and rows and cols of Ember.TextArea .

New attributeBindings for Ember.js text controls JSFiddle 1 2 3 4 5 6 7 8 9 10 Ember . TextField . create ({ maxlengthBinding : 'App.maxlength' , sizeBinding : 'App.size' }). append (); Ember . TextArea . create ({ rowsBinding : 'App.rows' , colsBinding : 'App.cols' , maxlengthBinding : 'App.maxlength' }). append ();

The event contextmenu has been added to Ember.EventDispatcher . All handled browser events and corresponding Ember.js equivalents are defined in Ember.EventDispatcher#setup.

From now on an Ember.Namespace needs to start with an uppercase letter. Just a reminder for the convention of naming classes and instances:

instances should start with a lowercase letter, so it’s App.controller = Ember.Object.create();

classes should start with an uppercase letter, so it’s App.Model = Ember.Object.extend();

This was a small roundup of the new stuff in Ember.js v0.9.6. Happy coding!