Hey everyone! Backbone 1.0 has been released! I just happened to pop by their site and see that 1.0 is official, so I have no idea how long it has been out. Why didn’t anyone tell me?!?!? Anyway, there may be some of you out there wondering what this new version brings and how they can update their apps to bring in all the new awesomeness. Well, let’s take a gander at this new stuff.
Events and Cleaning Them Up
This first new feature was mostly implemented just to help alleviate the problem known as zombie views. Zombie views are views that have been removed from the DOM and supposedly disposed of, but are still lingering around in memory, unable to be garbage collected. The reason they can’t be garbage collected is because they’re listening to events on another object (such as a model or collection), which means that references to the views have been stored in these objects.
To combat this issue, Backbone.Events
has gotten a couple new methods: listenTo
and stopListening
. Since Backbone.View
inherits the methods from Backbone.Events
, we now have these two methods available on our views. Now, rather than writing this:
1 | this.model.on('event', this.someMethod, this); |
…we can write this:
1 | this.listenTo(this.model, 'event', this.someMethod); |
…in our constructors. This gives us two things:
- The meaning is a little more clear and shows how we want the relationship to be. Now the method name indicated that we’re listening to an event rather than a callback being handed over to another object to be called when the event is fired. While this doesn’t actually change how the code works behind the scenes, it clarifies how we want the relationships to be.
- When we use
listenTo
, it stores the events that we’re listening to in the View too, so now we can just callstopListening
and it’ll remove all of the event listeners that we set up vialistenTo
.
As mentioned, stopListening
is the counterpart to listenTo
. Every event we register to via listenTo
will be unregistered when we call stopListening
. You can also specify which events and callbacks to unregister, just like when using off
on the model that you are listening to. So, if you just want to stop listening to the ‘change’ event on the model, you can call:
1 | this.stopListening(this.model, 'change'); |
The best part about stopListening
is that you don’t need to call it at all. When you call remove
on a view, stopListening
will also automatically be called. This means that if you want to dispose of a view, all you need to do is call someView.remove();
and you’re done (assuming you don’t have references to the view elsewhere).
This sort of functionality has been added in many Backbone extensions, but now it comes free with plain old Backbone. This may mean that if you update your version of Backbone, you’ll want to make sure that you also update your extensions to be sure that they aren’t conflicting with this new functionality.
Model Validation
No special new functionality has been added here, but some defaults and behaviors have changed. First of all, by default, models aren’t automatically validated when you call set
. The only time they are automatically validated is when you call save
. However, you can validate a model when you call set
by passing in the {validate: true}
option like this:
1 | model.set({'some':'property'}, {validate:true}); |
The other big change to validation is that an ‘invalid’ event will be fired, rather than ‘error’, so make sure that you change your listeners.
Collection Updates
In the old days, when you called fetch
on a collection, it would strip out all of its old models and just insert all the new ones that it retrieved. Now, it’ll try to update the collection by adding, removing, and merging models. Also, the collections’ update
method has been renamed to set
, so that it parallels the model’s method name. This is the method that fetch
uses to update the collection.
If you want to use the old functionality where fetch
would override all of the current models, you can pass in the {reset:true}
option.
Route Decoding
Previously, a Backbone.Router
would leave a URL segments as is before passing the arguments to the route handlers, but now if the URL segments have URL encoded data in them, the data will be decoded before passing it to the handlers. This ought to make it simpler to interpret handler arguments.
Conclusion
According to the docs on the Backbone Project Page, these are the “larger breaking changes”. These are some very nice changes, and I’m especially excited about the first one, even though I’ve moved on to using extensions like Marionette. There are plenty of other changes that you will probably want to take a look at if you’ve been using Backbone 0.9.2 or earlier, which you can see in the change log. All the versions after 0.9.2 are technically betas for 1.0, so you’ll want to take a look at the changes for each of those. There are plenty of breaking changes and added features that you won’t want to miss.