Question

I have View listening for an "add" event on a Collection. When the handler fires, the context is the Collection, even though I used _.bindAll() to bind it to the View. Is this a bug, or am I not understanding how this works? jsfiddle

V = Backbone.View.extend({
    initialize: function (options) {
        this.collection.on('add', this.onAdd);
        _.bindAll(this, 'onAdd');
    },
    onAdd: function () { console.log(this); }
});
c = new Backbone.Collection();
v = new V({collection:c});
c.add(new Backbone.Model());

Outputs:

e.Collection {length: 1, models: Array[1], _byId: Object, _events: Object, on: function…}
Was it helpful?

Solution

Put the bindAll method before the binding to collection statement This should work:

V = Backbone.View.extend({
initialize: function (options) {
    _.bindAll(this, 'onAdd');
    this.collection.on('add', this.onAdd);

},
onAdd: function () { console.log(this); }

});

UPDATE: It's possible not to use the _.bindAll method by applying the context in the .on() method

this.collection.on('add', this.onAdd, this);

OTHER TIPS

Your problem is when your call this.collection.on('add', this.onAdd); first an event is bound to the onAdd function with no context (this = collection at trigger time) and calling _.bindAll(this, 'onAdd'); doesn't override it.

Try to change the order :

    _.bindAll(this, 'onAdd');
    this.collection.on('add', this.onAdd);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top