This is a 5 part backbone.js hello world tutorial/application. https://web.archive.org/web/20180317062059/http://arturadib.com/hello-backbonejs/docs/3.html In part 3, the author’s illustrating how to use collections and models to store data and how to tie changes to the views.
I understand most of it, except this line
this.collection.bind('add', this.appendItem); // collection event binder
Is this ‘bind’ just binding context, or is it functioning as an ‘event’ such appendItem is called anytime that a model has been added?
I ask, because in the render method of the ListView, it’s explicitly calling appendItem method, so why is it bound to ‘add’
_(this.collection.models).each(function(item){ // in case collection is not empty
self.appendItem(item);
}, this);
Can someone please explain a little how that code is working. i looked through the documentation but couldn’t find an explanation of bind used in this way.
Full code
(function($){
¶
Item class: The atomic part of our Model. A model is basically a Javascript object, i.e. key-value pairs, with some helper functions to handle event triggering, persistence, etc.
var Item = Backbone.Model.extend({
defaults: {
part1: 'hello',
part2: 'world'
}
});
¶
List class: A collection of Items. Basically an array of Model objects with some helper functions.
var List = Backbone.Collection.extend({
model: Item
});
var ListView = Backbone.View.extend({
el: $('body'),
events: {
'click button#add': 'addItem'
},
¶
initialize() now instantiates a Collection, and binds its add event to own method appendItem. (Recall that Backbone doesn't offer a separate Controller for bindings...).
initialize: function(){
_.bindAll(this, 'render', 'addItem', 'appendItem'); // remember: every function that uses 'this' as the current object should be in here
this.collection = new List();
this.collection.bind('add', this.appendItem); // collection event binder
this.counter = 0;
this.render();
},
render: function(){
¶
Save reference to this so it can be accessed from within the scope of the callback below
var self = this;
$(this.el).append("<button id='add'>Add list item</button>");
$(this.el).append("<ul></ul>");
_(this.collection.models).each(function(item){ // in case collection is not empty
self.appendItem(item);
}, this);
},
¶
addItem() now deals solely with models/collections. View updates are delegated to the add event listener appendItem() below.
addItem: function(){
this.counter++;
var item = new Item();
item.set({
part2: item.get('part2') + this.counter // modify item defaults
});
this.collection.add(item); // add item to collection; view is updated via event 'add'
},
¶
appendItem() is triggered by the collection event add, and handles the visual update.
appendItem: function(item){
$('ul', this.el).append("<li>"+item.get('part1')+" "+item.get('part2')+"</li>");
}
});
var listView = new ListView();
})(jQuery);
Say your collection already has 10 models. Then you pass it to your view. You’d call
render()which triggers a loop ofappendItem()or what not. Your view is happy.Then you add a model to your collection. (Model 11)
Rather than re-render the whole thing, the
this.collection.on('add', this.appendItem, this)executes the function that adds a single item view to the already existing view list.That’s probably why it’s bound to the add event AND included in the render as a loop. One loops through an existing collection to generate views at the start. One takes care of any new models that are added after the view is initialized and rendered the first time.