Ember 1.3.0 and 1.4 Beta Released
We are pleased to announce that both Ember.js 1.3.0 and the first beta in the 1.4 series have been released. This comes as the third cycle of our six-week release process that began after 1.0 was released.
New in 1.3
Non-array Dependencies for ReduceComputed
Generally, using reduceComputed is all about efficiently computing the resulting value, but
occasionally you might need to recompute every time. It is now possible to instruct
reduceComputed to completely recompute when an item is added/removed (instead of calling
the addedItem and removedItem callbacks).
This is done by using either non-array dependent keys or adding .[] to an array dependency.
Take a look at the following example:
Ember.Object.extend({
// When `string` is changed, `computed` is completely recomputed.
string: 'a string',
// When an item is added to `array`, `addedItem` is called.
array: [],
// When an item is added to `anotherArray`, `computed` is completely
// recomputed.
anotherArray: [],
computed: Ember.reduceComputed('string', 'array', 'anotherArray.[]', {
addedItem: addedItemCallback,
removedItem: removedItemCallback
})
});
Testing
Testability of Ember applications is an ongoing priority, and the 1.3 release contains a number of updates that result in a dramatic improvement.
Custom wait() Hooks
You can now specify custom hooks to notify the asynchronous test helpers when all
async actions have completed. Under Ember 1.2 if you need to wait for an IndexDB
action, the default wait implementation would not wait until that
action finished. Now you can register your own hook that will instruct wait
that it is truly time to continue.
For example:
Ember.Test.registerWaiter(function() {
return hasPendingTransactions() == 0;
});
This instructs the wait helper that the async actions are not finished until
hasPendingTransactions is zero.
You can find more details here.
Lazy Routing
Under Ember.js 1.2 routing is started as soon as you boot your application and before
you call visit. This results in duplicate routing which slows down your tests and also
potentially causes your tests to be less isolated.
Under Ember.js 1.3 routing isn't started until you call visit for the first time. This
provides a couple of improvements to the way you test:
- You do not need to call
App.advanceReadiness()in your test setup since the application is automatically in a deferred state until callingvisit. App.reset()now leaves the application in the same state asApp.setupForTesting()(a deferred state).
You can find more details here.
Stubbable controllers Property
Prior to Ember 1.3 you could not easily stub out any dependencies specified with needs.
Now you can unit test controllers and stub their dependencies all within
TheControllerClass.create() instead of having to use a container, register stubbed
dependencies, and instantiate the controller via container.lookup().
Simplified example:
var BrotherController = Ember.Controller.extend({
needs: 'sister',
foo: Ember.computed.alias('controllers.sister.foo')
});
var broController = BrotherController.create({
controllers: {
sister: { foo: 5 }
}
});
equal(broController.get('foo'), 5, "`needs` dependencies can be stubbed");
Previously, specifying controllers to BrotherController would have resulted in an error,
and now under Ember.js 1.3 this works as expected.
Promise Improvements
Ember.js 1.3 has updated to RSVP 3.0.3 which brings considerable performance improvements, a number
of new features, and significantly improved documentation coverage.
RSVP has added a number of features that allow external tooling to be able to inspect and track the labels, states, and
values of promises. These improvements will be extremely useful when used with the next major
version of the Ember Inspector.
Which will allow you to see a tree of promises and inspect their names, state, and fulfilled/rejected values.
RSVP added a number of additional methods to Promise:
Promise.cast- Coerces the given argument into a promise, or returns the argument if it is already a promise.Promise.catch-catchis essentially syntactic sugar forthen(undefined, onRejection)which makes it the same as thecatchblock of atry/catchstatement.Promise.finally- The callback provided toPromise.finallywill be invoked regardless of the promises fate (both fulfilled and rejected promises). This is essentially similar to nativetry/catch/finallystatements.Promise.race- Will return a new promise which will be settled with the value of the first promise that settles. In other words: given an array of promisesPromise.racewill return the value from the first argument that settles (like the winner in a "race").
Please review the documentation for more information.
Other Improvements
As usual, there are a ton of bug fixes and small improvements in this release. You can see a list of all the changes in the CHANGELOG: