Last Updated: September 09, 2019
·
9.333K
· paulosborne

this.collection.each() accepts a context object (backbone)

Until recently, if I wanted to render a view for each model in a collection, I'd do it like this...

var _this = this;

this.collection.each(function ( page ) { 
    _this.$el.append( new PageView({ model: page }).render().el );
});

This seems to be a commonly used pattern, it's used in Marionette and Teaching Materials as shown below.

Backbone.Marionette

showCollection: function(){
    var that = this;
    var ItemView = this.getItemView();
    this.collection.each(function(item, index){
      that.addItemView(item, ItemView, index);
    });
 }

Teaching Materials - Backbone

var BookShelfView = Backbone.View.extend({
  render: function(eventName) {
    var self = this;
    this.collection.each(function (book) {
      var bookItemView = new BookItemView({model:book});
      self.$el.append(bookItemView.render().$el);
    });
    return this;
  }
});

I've always disliked creating a copy of the context, it just feels messy. However, it turns out that you can pass in an optional context with most of the collection methods in Underscore.

this.collection.each(function ( page ) { 
    this.$el.append( new PageView({ model: page }).render().el );
}, this);

It's only a small improvement, but it helps with readabilty and removes a few lines of boilerplate.

2 Responses
Add your response

Didn't know that. But maybe we could do better if we used CoffeeScript's fat arrow

over 1 year ago ·

Thanks. It works for initializing the collection as well:


var Picker = Backbone.Collection.extend({
model: Pin,
initialize: function(){
_.each(colors, function(element, index){
this.add({color: element, position: index});
}, this);

console.log(this);
}
});
</pre>
over 1 year ago ·