Friday, April 8, 2011

Backbone-Part 1: Intro and the Model

Update: second part is here

Since UI applications exist, MVC has always been the starting point for any design, sometimes presenting itself in slightly different forms like MVC2 or MVVM.

Since one image is worth 1000 words let's start with a diagram.

In very short terms:
  • The Model: represents the data and the logic to operate on it. It is usually further split into Domain Model (the data) and Business Model (the logic)
  • The View: displays the data to the end user and listens to the Model for updates so that it can refresh itself with up to date info
  • The Controller: listens to the view for user input and decides how to proceed accordingly: it can either execute some operation on the model or select a different view. The Controller also listens to the Model for some events and also in this case decides which action to take, if any.

But how does this applies to the Web? And specifically to Javascript-centric apps?

Again in very short terms:
  • The Model: the (domain) model is data coming from the server through Ajax calls to RESTful Web Services(the Business Model).
  • The View: is represented by the combination of HTML and CSS providing nice look and feel to the user
  • The Controller: is an event listener for browser events. It also listens for events coming from some background task, part of the business layer.

After this intro, let's move on to the main topic of this post: Backbone.
Backbone is a very light weight MVC framework, the minified version is about 4K. It is absolutely not invasive so that you can easily integrate it with JQuery and with any template technology.

In this part I will talk about the Model in Backbone, while in the second it will be the turn for View and Controller, which are actually combined.

A Model extend Backbone.Model, a prototype containing the following features:
  • CRUD operations: fetch(), save() and delete().
  • Get and Set methods to modify any field. Fields are stored in an hash-table...sorry I forgot in Javascript anything is an hash-table :)
  • validate(): you can override for custom validation, which does not mean you do not have to do it on the server side as well :)
  • parse(): if your server does not support JSON (what a pity), or you use any customized serialization strategy to speed up things, you can override this method
  • url(): override to specify the location of the resource for this model
  • Every time the state of the model has changed, events are fired for all eventual listeners

All CRUD operations actually delegates communication with the server to Backbone.sync().
By defaults standards REST operations are executed, but a lot of customization is allowed:
  • By setting Backbone.emulateHTTP=true, when you modify an object a POST will be executed in place of a PUT, same thing for DELETE operations.
  • By setting Backbone.emulateJSON=true instead of uploading a JSON payload in the HTTP request, a form submission will be simulated while JSON will be send as a parameter named "model".
  • If any of those options does not suit your needs yet, you can override Backbone.sync(method,model,success,error) which is quite simple and intuitive

And about the last point, using the localStorage during development can save A LOT OF TIME by just refreshing the browser instead of having to re-compile and re-deploy every time! A simple localStorage-based implementation can be found here.

But what about if I want to fetch my model in batches and not one by one? Of course you can!
Extending Backbone.Collection allows you to manage a collection of models.
And even better, you can invoke on a Backbone.Collection all of the Underscore functions.

For large enough Collections it is preferred to use pagination, but I will talk more about this next time...


  1. MVC2 is a variant of the classical MVC and it was introduced some years ago by the Struts framework, you can find more details here:

  2. "validate(): you can override for custom validation, which does not mean you do have to do it on the server side as well :)"

    except for SQL injection checking, of course ;-)