Backbone in baby steps, Part 1

In this tutorial we will be building a library application for managing digital books using Backbone. We will also have a glimpse at Underscore and jQuery since they are the default requirements of Backbone.

Backbone

Backbone is an MVC-style framework for building applications. It is not a true MVC framework, since it doesn’t have a controller, the controller responsibilities lies instead on the view. In addition to model and view, Backbone also has Collection for grouping models together, and router for handling url routes.

So this is what we want the final result to look like, but with more books. Go ahead and copy the bookContainer div a couple of times if you would like to see what it looks like. Now we are ready to start developing the actual application. Open up app.js and enter this:

This is our model of a book. It contains a defaults property that gives us default values for all the values we want our model to contain. Note that I have wrapped everything in a self executing function with the argument “jQuery”. This is standard procedure to prevent polluting the global scope and to avoid any collisions with the $ variable. The model in itself isn’t very useful so we need to pair i with a View. For the view we need a template so open up index.html and create a template from our bookContainer we created earlier:

So what’s going on here? Well, I have wrapped the template in a script tag with the type “text/template”. By doing this the browser will not recognize the type and not render it, but we can still access all the elements in JavaScript. I have removed the surrounding div tag since the templating engine (Underscore) will create that for us. In the various fields I have inserted <%= field %> that Underscore will find and replace with real data. Now that we have our template in place we can go and create the view, so switch over to app.js:

So the view works like the model in that we use the extend function and pass it properties. The tagName property defines the container of the view, the className defines the class of the container and template is, well, the template for the view. The render function creates the tmpl function by calling underscores template function with one argument (the template from our index.html). It then calls the tmpl function with our model… wait a minute! What model? Well, this is something that we need to provide as an argument when we call out view constructor. As it looks now our view isn’t connected to any element in out html page either, so let’s take care of that now:

Here we have created a new Book model by calling the Book constructor and passing an object with our desired properties. The model is then used when creating a BookView. Finally the bookView is rendered and inserted into our page. It should look something like this:

Looking good, we now have a working Backbone application. Since a library cannot contain just one book, we need to push further. Lets have a look at Collections. Collections contain collections of models. The models must be of the same kind, ie you cannot mix apples and bricks in the same collection. Other than that, collections are quite simple, you just tell them what kind of models they contain like this:

varLibrary = Backbone.Collection.extend({
model:Book
});

Go ahead and insert the code in app.js. Next stop is a new view for our Library collection. This view is a bit complicated than the earlier BookView:

I added some line numbers to help me explain what is going on. On line 02 I specified the property “el”. A view can take either a tagName, as we saw in our BookView, or an el. When we use tagName, the view will create the element for us, but we are responsible for inserting it into the page. When we use el we specify an existing element in the page and the view will write directly into the page, into the specified element. In this case we select the div with id=”books”.

Next on line 04 is the initialize property. This is a special (but optional) property that must contain a function. This function will be called by Backbone when the view constructor is called. On line 05 in we create a new Library (collection of Book models) and store it in a local property called “collection”. On line 06 it call its own render function, which means that as soon as we call the LibraryView constructor it will get rendered, so this is a self rendering view. We don’t have to make it self rendered but it is common practice.

On line 10 in the render function we store a reference to the current object in a variable “that” and then (on line 11) use the each function of underscore to iterate over all the models (Books) in our collection. The first argument to “each” is the array that will be iterated over. The second argument is the function that will be applied to each member of the array. The function in our case calls the renderBook function with the current model as argument. We need to use “that” to get this right since if we would have used “this” it would have referenced the function itself. The third argument (line 13) is the context that each is executing in.

On line 16 we define a function renderBook that takes a model (a Book) as argument and uses it to create a BookView. The bookView is then rendered and appended to the view container as specified in our el property (on line 02).

You may have noticed that on line 05 we called the Library constructor with the argument “books”. Library is a Backbone collection that expects an array of objects that it can use to create Book models. We haven’t defined the books variable yet so lets go ahead and do that:

Great observation. So I saved the scope of the render function in a variable ‘that’ to be able to access it in the ‘each’ function parameter, but since the third parameter to ‘each’ is the scope that the supplied function will execute in, the whole ‘that’ thing is not necessary. Also applying ‘each’ directly to the collection is very neat. Thanks!

If you put the scripts between the head tags, you’ll get a JavaScript error in underscore.js. I didn’t even this was a potential problem, and I am not sure why it was, but it is and I only noticed it when I couldn’t get the code to work using some pre-made templates I had for testing new code; the code worked perfectly when I left it as in the code… and now I am wondering if it is because of the #bookTemplate script. I’ll have to play with this, but it was interesting enough of issue for me while learning that I thought I’d share.

You really make it seem so easy along with your presentation but I in finding this topic to be actually something which I feel I’d by no means understand. It sort of feels too complicated and very broad for me. I am having a look forward on your subsequent post, I’ll try to get the dangle of it!

Excellent tutorial. I’ve purchased a video course, read lots of different articles on Backbone and know quite a bit, but I was confused about how all the different components of Backbone all go together – I had a patchwork of elements. This is a very good example that sews together Model. View and Collection. Now I “get it” and I can re-read other stuff and understand the wider context.
Thank you very much! This is a brilliant way to introduce Backbone, and should be linked to from http://www.backbonejs.org!

Great tutorial. One correction: img/placeholder.gif should be img/placeholder.png and would be good to remind those of us who are a bit slow (!) to update the script source urls to e.g. js/jquery-1.10.2.min.js. Thanks.

Hello Kushal,
I’m not sure what you mean here, but using Mysql instead of Mongo should be fine. You probably need to take care of serialisation/deserialisation since Mysql is a relational database. The part of keeping the app in sync with the database might be a bit more complicated since the server needs some way to tell when the data changes and then some way to tell the web app that data is changed. Should be doable with database hooks and websockets but all this is probably more suitable for another blog post.