Spinal Surgery: Upgrade to Backbone 1.0

Upgrading to Backbone 1.0Hey 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:

this.model.on('event', this.someMethod, this);

…we can write this:

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 call stopListening and it’ll remove all of the event listeners that we set up via listenTo.

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:

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:

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.

About the Author

Author: Joe Zim

Joe Zim

Joe Zimmerman has been doing web development ever since he found an HTML book on his dad's shelf when he was 12. Since then, JavaScript has grown in popularity and he has become passionate about it. He also loves to teach others though his blog and other popular blogs. When he's not writing code, he's spending time with his wife and children and leading them in God's Word.