HTML5 Zone is brought to you in partnership with:

I'm software developer and microISV, with a lot of passion to technologies.. having a fun writing code, writing blog posts and giving public speeches. For about 10 years of total experince I've been working in many branches of software development, including management and QA. I try to follow and adopt agile practices and signed up for software craftsmenship manifesto. Alexander is a DZone MVB and is not an employee of DZone and has posted 67 posts at DZone. You can read more from them at their website. View Full User Profile

Baby steps to Backbone.js: Exploring collections. Part 2.

04.12.2013
| 3607 views |
  • submit to reddit

Backbone.js is event-driven framework. All Backbone entities are extended from Backbone.Event object. That means, they are able to raise events, subscribers are able to listen to that events and act accordingly. Let's take a look what type of event does Backbone.Collection have.

Backbone.Collection events

Will have a test suite for that,

describe('collection events', function () {
    var listener;
 
    beforeEach(function () {
        collection = new FeedbackCollection();
    });
 
    beforeEach(function () {
        listener = jasmine.createSpy();
    });

Here we are creating collection for testing and Jasmine spy, special function we going to use as event subscriber.

Adding element to collection

As we saw previously there are several ways of adding new elements to collection. By add and push methods. The important thing, does not matter what API method you use, Backbone.Collection would trigger 'add' event.

By add method,

describe('while adding elements', function () {
    beforeEach(function () {
        collection.on('add', listener);
    });
 
    beforeEach(function () {
        collection.add({id: 'feedback-1', email: 'a@a.com', website: 'a.com', feedback: 'hello'});
    });
 
    it ('should raise add event', function () {
        expect(listener).toHaveBeenCalled();
    });
});

By push method,

describe('while pusing elements', function () {
    beforeEach(function () {
        collection.on('add', listener);
    });
 
    beforeEach(function () {
        collection.push({id: 'feedback-1', email: 'a@a.com', website: 'a.com', feedback: 'hello'});
    });
 
    it ('should raise add event', function () {
        expect(listener).toHaveBeenCalled();
    });
});

Each event handlers receives model itself and reference to collection.

Removing elements from collection

Similarly, there 2 ways of removing items from collection, by remove and pop methods.

By remove method,

describe('while removing items', function () {
    beforeEach(function () {
        collection.on('remove', listener);
    });
 
    beforeEach(function () {
        collection.add({id: 'feedback-1', email: 'a@a.com', website: 'a.com', feedback: 'hello'});
        var model = collection.get('feedback-1');
        collection.remove(model);
    });
 
    it ('should raise remove event', function () {
        expect(listener).toHaveBeenCalled();
    });
});

By pop method,

describe('while poping items', function () {
    beforeEach(function () {
        collection.on('remove', listener);
    });
 
    beforeEach(function () {
        collection.add({id: 'feedback-1', email: 'a@a.com', website: 'a.com', feedback: 'hello'});
        collection.pop();
    });
 
    it ('should raise remove event', function () {
        expect(listener).toHaveBeenCalled();
    });
});

Resetting and sorting

Besides just adding and removing stuff from collection, it have few more method which reaction is triggering event. It's reset and sort. Reset is the bulk insert into collection, it works great when we fetch some data from server and want to push everything just by one operation. Sort, is rarely called manually, since if collection provides comparator function, it would sort itself, during add or reset operations. But sometimes sorting could be triggered from UI as user changes the sort column of table, for example.

Resetting collection,

describe('while reseting collection', function () {
    beforeEach(function () {
        collection.on('reset', listener);
    });
 
    beforeEach(function () {
        collection.reset([
            {id: 'feedback-1', email: 'a@a.com', website: 'a.com', feedback: 'hello'},
            {id: 'feedback-2', email: 'b@b.com', website: 'b.com', feedback: 'good bye'}]);
    });
 
    it('should raise reset event', function () {
        expect(listener).toHaveBeenCalled();
    });
});

Sorting collection,

describe('while sorting collection', function () {
    beforeEach(function () {
        collection.on('sort', listener);
    });
 
    beforeEach(function () {
        collection.reset([
            {id: 'feedback-1', email: 'a@a.com', website: 'a.com', feedback: 'hello'},
            {id: 'feedback-2', email: 'b@b.com', website: 'b.com', feedback: 'good bye'}]);
        collection.sort();
    });
 
    it('should raise sort event', function () {
        expect(listener).toHaveBeenCalled();
    });
});

Why it matters?

Knowing the events of all Backbone.js entities is very important. You should always design you application based on events triggering/subscription, instead of direct function call. That would make your code much de-coupled and UI logic very flexible.




Published at DZone with permission of Alexander Beletsky, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)