Over the last month we've looked at Backbone's internals in detail. This post summarises these findings.
To recap, here's a list of all the parts in Backbone.js: Hacker's Guide:
- Part 1: Setup, Events, Models
- Part 2: Constructor, Inheritance, Collections, Chainable API
- Part 3: Router, History, Views
- Part 4: Inheritance, Sync
Backbone's classes are designed to be inherited from. Every single one of these classes inherits from
That means when designing applications built with Backbone, events are a key architectural component. Events are the standard way to deal with user interface actions, through the declarative event bindings on views, and also model and collection changes. However, you can easily add your own custom events.
When learning Backbone it's important to get a feel for the built-in event names. Incorrectly binding a collection
reset event, for example, could cause your application to render more often than it should. Mastering events is one of the quickest ways to become more productive with Backbone.
Since Backbone depends on Underscore, it's worth keeping this in mind when dealing with any kind of arrays or collections of data. Also, familiarity with Underscore's methods will help work with
It's easy to slip into using
$, but avoid this where possible. Backbone caches a view's element, so use
this.$el instead. Design views based on the single responsibility principle.
It might be tempting to let "container" view render HTML directly by using
$().html, but resisting the temptation and creating a hierarchy of views will make it much easier to debug your code and write automated tests.
Interestingly, Backbone doesn't have a lot of code dedicated to templates, but it can work with the template method. I use this with RequireJS text file dependencies to load remote templates during development, then I use the RequireJS build script to generate something suitable for deployment. This makes code easy to test and fast to load.
Backbone's API is thankfully very consistent. Even the history API accepts a
silent option, which is used throughout the library to stop events from firing when they're not required.
Backbone's collections have Underscore's chainable API, which can be handy, but care must be taken to use this correctly.
So far I've been reviewing Backbone's code to demystify the framework as a whole. However, it's worth noting that other technologies work very well with Backbone and Underscore. RequireJS and AMD modules can be a great way to break up projects.
However, one area that Backbone doesn't address is testing. This is unfortunate, because testing Backbone projects definitely isn't obvious. In Unit Testing Backbone.js Apps With QUnit And SinonJS, Addy Osmani describes one method in detail.
I have the following rules for testing Backbone projects:
- The full application should be running during testing
- Tests shouldn't depend on any markup in the test harness HTML file (or as little as possible)
- Tests shouldn't touch the network for data
The second rule in particular is aided by using templates loaded by RequireJS and avoiding those pesky calls to
$() in views.