Backbone.js

A gentle introduction to a JavaScript library

Arc90 University | May 24th, 2012

What is Backbone.js?

http://documentcloud.github.com/backbone/

What is Backbone.js?

We're going to look at a simple photo app backed by a local server & DB.
Fork it on GitHub: https://github.com/DarrenN/backbone-demo

Enough Talk.
Let's see some code.

(We'll take a quick tour of the basics first)

Models

Lets make a simple model to store our a photo

            
// The app uses a set of photos taken from my Instagram feed via Statigram,
// hence the namespace
var Statigram = {};

// Define a Model
Statigram.Photo = Backbone.Model.extend({
    initialize : function() {
        log(this.id);
    }
});

// Create a new Photo model with an id = 1
var photo = new Statigram.Photo({ id : 1 });
            
        

Models

Now let's sync the model to the server and retrieve the record for Photo.id = 1

            
var Statigram = {};

Statigram.Photo = Backbone.Model.extend({

    // Set a base URL for the model to hit. Backbone will create the url:
    // Request: GET http://arcane-refuge-8744.herokuapp.com/photo/1
    urlRoot : 'photo',

    initialize : function() {
        // fetch() uses Backbone.Sync to hit the server and
        // load the model with the returned JSON
        this.fetch({
            success : function(model, response) {
                // Use get() to grab model attributes
                log(model.get('title') + ' : ' + model.get('link'));
            }
        });
    }
});

var photo = new Statigram.Photo({ id : 1 });
            
        

Models

Now let's make a change and persist it to the DB

            
var Statigram = {};

Statigram.Photo = Backbone.Model.extend({
    urlRoot : 'photo',

    initialize : function() {
        // After saving a sync event is fired to get the model up to date
        // so we'll watch for that event and act on it
        this.on("sync", function(model, response){
            log(model.get('title'));
        })
    }
});

var photo = new Statigram.Photo({ id : 1 });
photo.save({'title' : 'Jo Bob'});
            
        

Collections

Manage a bunch of models using Underscore.js and other goodness

            
var Statigram = {};
Statigram.Photo = Backbone.Model.extend({}); // Model

// Make a Collection object
Statigram.Photos = Backbone.Collection.extend({
    url   : '/photos',
    model : Statigram.Photo // Explicitly tell it what model to use
});

// Create a collections and add some models
var photos = new Statigram.Photos();
photos.add([
    { id : 1 },
    { id : 2 },
    { id : 3 }
]);
log([photos.length, JSON.stringify(photos)]);
            
        

Collections

Use fetch() to populate a Collection from the server. In this case we'll get the whole DB back (12 rows) loaded into models.

            
var Statigram = {};
Statigram.Photo = Backbone.Model.extend({}); // Model

// Make a Collection object
Statigram.Photos = Backbone.Collection.extend({
    url   : '/photos',
    model : Statigram.Photo // Explicitly tell it what model to use
});

// Create a collections and add some models
var photos = new Statigram.Photos();
photos.fetch({
    success : function() {
        // Notice .pluck() - a nice bit of Underscore.js to help manage models
        log([photos.length, JSON.stringify(photos.pluck('title'))]);
    }
});
            
        

Collections: Manipulation

Like pluck() there are a bunch of available functions you can use to operate on and iterate over your collection of models (map(), reduce(), shuffle(), etc…)

            
var Statigram = {};
Statigram.Photo = Backbone.Model.extend({});
Statigram.Photos = Backbone.Collection.extend({ url   : '/photos', model : Statigram.Photo  });
var photos = new Statigram.Photos();
photos.fetch({
    success : function() {
        // Iterate the collection with .each()
        photos.each(function(model){ log(' Id: ' + model.id) });

        log([
            // Get a model from collection by Id
            photos.get(3).get('title'),

            // Get models that meet a criteria and return array
            photos.where({title : 'Kawaii'})[0].get('title'),

            // Pop - pop last model off stack and return it
            photos.pop().get('title')
            ]);
    }
});
            
        

Views

Now that we have data, we need to display it in a meaningful manner. Views will auto-assemble DOM elements for you based on the information you give it.

            
var Statigram = {};
Statigram.PhotoView = Backbone.View.extend({
    tagName   : 'li', // We want to make list elements
    className : 'photo_view', // we would like this className
    render    : function() {
        // The view generates `this.el` out of the tagName & className to make:
        // <li class="photo_view"></li>
        //
        // $el - this is `this.el` wrapped in jQuery
        this.$el.html('A list element of stirling reputation.');
        log(this.el);
    }
});
var photo_view = new Statigram.PhotoView();
photo_view.render();
            
        

Views

Use your collection and models to load data into your views.

            
var Statigram = {};
Statigram.Photo = Backbone.Model.extend({
    initialize : function() {
        this.view = new Statigram.PhotoView({ model : this, id : this.id });
        this.view.render();
    }
});
Statigram.Photos = Backbone.Collection.extend({
    url : '/photos', model : Statigram.Photo
});
Statigram.PhotoView = Backbone.View.extend({
    tagName   : 'li',
    className : 'photoview',
    render    : function() {
        $('#test_list').append(this.$el.text(this.options.model.get('title')));
    }
});
photos = new Statigram.Photos();
photos.fetch(); // Load models from server and render
            
        

Views

Attach events to your views to keep your code organized.

            
var Statigram = {};
Statigram.Photo = Backbone.Model.extend({
    initialize : function() {
        this.view = new Statigram.PhotoView({ model : this, id : this.id });
        this.view.render();
    }
});
Statigram.Photos = Backbone.Collection.extend({ url : '/photos', model : Statigram.Photo });
Statigram.PhotoView = Backbone.View.extend({
    tagName   : 'li',
    className : 'photoview',
    render    : function() { $('#test_list2').append(this.$el.html(this.options.model.get('title'))); },
    events    : {
        "click" : "red"
    },
    red : function(e) {
        this.$el.css({ color : '#f00' });
        log(" ID:" + this.$el.attr('id'));
    }
});
photos = new Statigram.Photos();
photos.fetch(); // Load models from server and render
            
        

Hopefully that
made sense.

Now lets look at the app