Backbone.JS Tutorial part 2

Here’s the 2nd post on Backbone.js. If you missed the first one check it out here.

This time I’ll cover the Backbone.Collection component, it’s basics and how useful they can be.

Collections

Collections represent an agregation of Models. The collection’s models can either be an object (which will be translated into Backbone Models):

> var RawCollection = Backbone.Collection.extend({});
> var foo = new RawCollection([ {bar:"1"},
                        {bar:"2"} ]);

Or an existing model, in this case, our `Book`:

> var BooksCollection = Backbone.Collection.extend({
  model: Book,
    url: '/books'
});

The way to access the whole list of models on your collection is:

> foo.models;
< [Backbone.Model, Backbone.Model]

push(), add() and reset()

Pushing models to your collection is pretty simple too:

> foo.push({bar:"3"});
> foo.length;
< 3
> // or you may want to push an array of models
> foo.add([{bar:"4"}, {bar:"5"}]);
> foo.length;
< 5

Resetting your collection removes all the models from it:

> foo.reset();
> foo.length;
< 0

pluck()

Pluck returns an array with the specified attribute from your collection’s models.

> foo.reset()
> foo.push([
  {bar: 1},
    {bar: 2},
    {bar: 3}]);
> foo.pluck('bar');
< [1,2,3]

comparator

Setting the collection comparator automatically sorts the collection on insertion:

> foo.reset()
> foo.comparator = 'baz';
> foo.push([
  {bar: 1, baz: 'z'},
    {bar: 2, baz: 'y'},
    {bar: 3, baz: 'x'}]);
> foo.pluck('bar');
< [3,2,1]

where() and findWhere()

These are used to query the collection for retrieving models.

> foo.reset()
> foo.push([
  {bar: 1, baz: 'z', qux: 1},
    {bar: 2, baz: 'y', qux: 2},
    {bar: 3, baz: 'x', qux: 1}]);
> var result = foo.where({qux: 1});
< [Backbone.Model, Backbone.Model]
> result.length;
< 2
> result[0].bar;
< 1
> result[1].bar;
< 2
> // you may join several attributes
> result = foo.where({qux: 1, baz: 'x'});
< [Backbone.Model]
> result[0].bar;
< 3
> // when querying to get one/the first result, use findWhere
> result = foo.findWhere({bar: 1});
< Backbone.Model
> result.toJSON();
< {bar: 1, baz: 'z', qux: 1}

fetch()

Remember the url on the BooksCollection? This defines the API endpoint for the Collection. Cool thing is that it also applies to the model it encloses! This means if you follow the rules, you won’t have to define the url attribute to your models as we did in the previous post.

fetch() will make a GET request to the url endpoint, which for BooksCollection is /books.

> var Book = Backbone.Model.extend({
    // no url here!
  defaults: {
      'type':'hardcover'
    }
});
> var books = new BooksCollection();
> books.fetch();
> books.length;
< 2
> books.pluck('id');
< [1,2]
> // pretty neat, let's play around with it's models
> books.first().toJSON();
< { title: 'Fahrenheit 451', author: 'Douglas Adams', type: 'paperback', 'number_of_pages': 251 }
> books.first().save({'number_of_pages': 192});

This last save() will POST this model to the URL /books/1, which is the collection’s URL with the model ID. Backbone is smart enough for this :-)

events

Just like what happens with models, collections also trigger events whenever you change them in some way. The possible events are: "change", "add", "remove" and "reset". We’ll get into this on the next post!

The next post will be about Backbone.View which handles rendering the eye candy on your web-app!

Feel free to leave props or flames in the comment section ;-)