I bring it up in this post because code samples later will utilize it. For the basics, check out the overview—it should be plenty to allow you to grok the code in this post.
Backbone.js is the library that really helped bring shape to my code. It provides models, collections, views, routing and more. Your views respond to events in your models or collections to get stuff done. It even has “magic support” for jQuery, so you don’t have to write UI code without it.
My application was a World of Warcraft server status page designed to demonstrate some new API’s that Blizzard is providing. I wanted it to be able to show the current status of every server (fetched via JSONP and refreshed every five minutes) and I wanted the list to be searchable with an input box on the page. Let’s take a look at the various pieces of the app.
First, I created a model for a single server (aka “realm”). This model holds the name of the realm, its type, current population, whether or not the server is running, and whether or not there is a queue to play on the server. (Although it’s not necessary to set defaults, as all poperties are set automatically from JSON later, I did so here.)
Next up, I created a collection to hold a list of models. It’s through this object that I fetch new data from the JSONP endpoint and update the models accordingly.
I struggled with this for a little while, as Backbone is really designed to help where CRUD and REST are in heavy use. For example, a call to
RealmList.fetch() replaces all the models it holds with new models rather than updating the old models. This wasn’t exactly what I wanted, and since I had to update the entire list of realms via JSONP every time, I did a bit of hackery to overide the collection’s
refresh function after the initial download.
The other thing to note here is the
_.bindAll method. This is an Underscore.js method (Backbone depends on Underscore) that ensures that anytime any of the named methods are invoked, they are called in the context of the current object (so
this always refers to the object where the method lives).
Next up is the view for a single realm; that is, one instance of a server in the list.
Notice the call to
div on the page, and read that HTML in to the template. In a larger app, I would probably use Milk for rendering templates.
Also, it’s easy to miss the magic here; it’s really only one line:
this.model.bind 'change', this.render
This line of code binds its model’s
change event to the view’s
render element; the end result is that the view will automatically re-render itself any time its model’s data changes.
Finally we get to the view for the application; while it’s a bit longer than the other objects, it’s actually relatively simple, mostly taking responsibility for binding various UI changes to events from the realm list.
It’s also primary responsible for handling the search functionality for the app, iterating over the list of realms and checking to see if the name starts with the serch string, and hiding or showing the views accordingly. It does this when it receives the
filter:change event fired from
RealmList.filter. But how does that method know when to fire that event? The answer comes from our last object, the controller.
The controller is analagous to the router in a traditional Rails app; it handles changes in the hash string. Here’s our controller:
The controller simply takes any hash string and passes it on to the realm list, which then fires the necessary event so that the view does the filtering.
I hope this post has given you a glimpse into the power of Backbone (and the syntax of CoffeeScript). There’s a bit more code I didn’t go over (and parts of the code that I did show that I glossed over). Please feel free to take a look at the complete CoffeeScript source for the app; you can also find a snapshot of the code from the time I wrote this post, and you can check out the entire project’s source if you’re interested). Don’t hesitate to comment here or shoot me an email if you have any questions.