Subscribe via RSS Feed

Collections in Backbone.js

April 22, 2014 6 Comments

Backbone collections are simply an ordered set of models. By using Models and Collections we can avoid putting data manipulation logic into our Views. Plus, Models and Collections provide convenience methods for working with a back end, and can automatically signal Backbone Views when the data changes. Such that it can be used in situations such as -
Model: Animal, Collection: Zoo

Typically your collection will only use one type of model but models themselves are not limited to a type of collection -

Model: person, Collection: Office
Model: person, Collection: Home

Here is a generic Model/Collection example.

  var Music = Backbone.Model.extend({
      initialize: function(){
          console.log("Welcome to the music world");
      }
  });
  var Album = Backbone.Collection.extend({
    model: Music
  });

The above code shows us to create collections. But it doesn’t tell us the process to populate the collections with data. So, let us explore the process through a set of codes.

var Music = Backbone.Model.extend({
        defaults: {
            name: "Not specified",
            artist: "Not specified"
        },
        initialize: function(){
            console.log("Welcome to the music world ");    }
    });
    var Album = Backbone.Collection.extend({
        model: Music
    });
    var music1 = new Music ({ id: 1 ,name: "How Bizarre", artist: "OMC" });
    var music 2 = new Music ({id: 2,  name: "What Hurts the Most", artist: “Rascal Flatts" });
    var myAlbum = new Album([music 1, music 2]);
    console.log( myAlbum.models ); 

In the following we can see the relationship of collection and other components of backbone:

collection

Add models to a collection:
As we know collections are a collection of models.So,we can add models to a collection. To add models to a collection we can use the “add” method.we can also add a model to the beginning of a collection by using the unshift() method.

var music3 = new Music({ id: 3, name: "Yes I Do",artist:“Rascal Flatts"  });
Music.add(music3);
console.log('New Song Added');
console.log(JSON.stringify(Music));

Remove models from a collection:
Many times we will feel the need to remove some specific data from a collection.To remove a model from a collection, we can provide the id of the model that we want to remove.If we want to replace a collection with a completely new set of data.We can use the reset method. We’ve made a bunch of changes to our current collection. Let’s start over by passing the original array back in.

Music.remove(1);
console.log('How Bizarre removed...');
console.log(JSON.stringify(Music));

Get & Set:
When we need to get a value from a collection from somewhere else in code, using the get method is fairly straightforward. We can pass in the id value to retrieve the model that we want to get.

console.log(JSON.stringify(Music.get(2)));

The set method for a collection has an interesting implementation.The set method performs a “smart” update of the collection with the passed list of models. If a model in the list isn’t yet in the collection it will be added. If the model is already in the collection its attributes will be merged. And if the collection contains any models that aren’t present in the list, they’ll be removed.
So let’s take a look at this in action:

 var Music = Backbone.Model.extend({ 
        // This attribute should be set as a default
        defaults: {
            Name: ''
        },
        // Set the id attribute so that the collection         
        idAttribute: 'id'
    });
    var song = Backbone.Collection.extend({
        model: Music
    });
    var models = [{
        Name: 'OMC',
        id: 1
    }, {
        Name: 'Flatts',
        id: 2
    }];
    var collection = new song(models);
    collection.bind('add', function (model) {
        alert('addb')
    });
    collection.bind('remove', function () {
        alert('add')
    });
    models = [{
        Name: 'OMC',
        id :1
    }, {
        Name: 'Flatts',
        id: 2
    }, {
        Name: ' Jackson ',
        id: 3
    }];
    collection.add(models);
});

As we can see in the above , though we have 2 models beforehand. When we add the third model , the previous models remain unchanged. And the third model is added.

constructor / initialize:
When creating a Collection,we can pass in the initial array of models. The collection’s comparator may be included as an option. Passing false as the comparator option will prevent sorting. If we define an initialize function, it will be invoked when the collection is created. There are a couple of options that, if provided, are attached to the collection directly: model and comparator.

var tabs = new TabSet([tab1, tab2, tab3]);
var spaces = new Backbone.Collection([], {
  model: Space
});
toJSON:

Returns an array containing the attributes hash of each model in the collection. This can be used to serialize and persist the collection as a whole. The name of this method is a bit confusing, because it conforms to JavaScript’s JSON API.

var song = new Backbone.Collection([
  {name: "Flatts"},
  {name: "OMC"},
  {name: "Jackson"}
]);
alert(JSON.stringify(song));

comparator:
By default there is no comparator for a collection. If we are to define a comparator, it will be used to maintain the collection in sorted order. This means that as models are added, they are inserted at the correct index in collection.models. A comparator can be defined as a sortBy , as a sort , or as a string indicating the attribute to sort by.
“sortBy” comparator functions take a model and return a numeric or string value by which the model should be ordered relative to others.
“sort” comparator functions take two models, and return -1 if the first model should come before the second, 0 if they are of the same rank and 1 if the first model should come after.
Below we are going to see this method sorting the roll numbers of students in a proper order:

var student  = Backbone.Model;
var students = new Backbone.Collection;
students.comparator = 'name';
students.add(new student({name: "name1", roll: 9}));
students.add(new student({name: "name2", roll: 5}));
students.add(new student({name: "name3", roll: 1}));
alert(students.pluck('roll'));

Collections with a comparator will not automatically re-sort if we later change model attributes, so we should call sort after changing model attributes that would affect the order.

sort:
Forces a collection to re-sort itself.as a collection with a comparator will sort itself whenever a model is added. To disable sorting when adding a model, pass {sort: false} to add. Calling sort triggers a “sort” event on the collection.below we can see a basic set of coding for sorting.
we would only need one collection function.

sortByType: function(type) {
  this.sortKey = type;
  this.sort();
}

And one view function:

sortThingsByColumn: function(event) {
  var type = event.currentTarget.classList[0]
  this.collections.things.sortByType(type)
  this.render()
}

pluck:
Plucks an attribute from each model in the collection. Equivalent to calling map and returning a single attribute from the iterator.

var song = new Backbone.Collection([
  {name: "Flatts"},
  {name: "OMC"},
  {name: "Jackson"}
]);
var names = songs.pluck("name");
alert(JSON.stringify(names));

where:
Returns an array of all the models in a collection that match the passed attributes. Useful for filters.

var song = new Backbone.Collection([
  {name: "Yes I Do",      artist: "Flatts"},
  {name: "How Bizarre",    artist: "How Bizarre"},
  {name: "What Hurts the Most",     artist: "Flatts"},
  ]);
var artists = song.where({artist: "Flatts"});
alert(artists.length);

URL:
Sets the URL property on a collection to reference its location on the server. Models within the collection will use URL to construct URLs of their own.

var Songs = Backbone.Collection.extend({
  url: '/songs'
});
var Songs = Backbone.Collection.extend({
  url: function() {
    return this.document.url() + '/songs';
  }
});

parse:
parse is called by Backbone whenever a collection’s models are returned by the server, in fetch. The function is passed the raw response object.it should return the array of model attributes to be added to the collection. The default implementation is a no-op. simply passing through the JSON response. Override this to work with a preexisting API, or better namespace responses.

var songs = Backbone.Collection.extend({
    parse: function(response) {
    return response.results;
  }
});

fetch:
Fetches the default set of models for this collection from the server, setting them on the collection when they arrive. The options hash takes success and error callbacks which will both be passed (collection, response, options) as arguments. Then the model data returns from the server.It uses set to merge the fetched models. Delegates to Backbone.sync under the covers for custom persistence strategies and returns a jqXHR. The server handler for fetch requests should return a JSON array of models.

Backbone.sync = function(method, model) {
  alert(method + ": " + model.url);
};
var songs = new Backbone.Collection;
songs.url = '/songs';
songs.fetch();

All the things that we have seen in the above article are achieved and refined in other ways to make the code easy. Just like this backbone.collection also has many underscore methods that could be used for making better quality of coding.

Some related articles :

1>Introduction to Backbone.js

2>Models in Backbone.js

3>Understanding view in Backbone.js

4>Underscore Methods in Backbone.js

5>Backbone Routes and History</

6>Templates In Backbone.js

7>WHY SHOULD WE USE SERVER SIDE IN BACKBONE.JS?

8>Backbone.js at a glance

We will have other detail of Backbone features in our later articles. So please look for the same.
If you find this article helpful, you can connect us in Google+ and Twitter.

Sign Up to read the rest of the content

Email will be used only for updates of our site

No Thanks

Filed in: Backbone.js