Binding Backbone Callbacks

There’s one thing about JavaScript that’s always been an issue for me and that’s remembering to bind callback methods to the correct scope. For some reason I always forget and then spend an age trying to figure out why things aren’t working correctly. I’m forever doing this kind of thing in a Backbone view:

Backbone.View.extend({
events: {
'click a.enable': 'enableHandler',
'click a.disable': 'disableHandler'
},
initialize: function() {
this.model = new Model();
this.model.bind('change', this.render, this);
}
// ...
enableHandler: function(e) {
e.preventDefault();
this.model.save({
enabled: true
}, {
wait: true,
success: function() {
this.$('a.enable').hide();
this.$('a.disable').show();
},
error: function() {
// ...
}
});
}
// ...
});
view raw NoBinding.js hosted with ❤ by GitHub

I’m then left wondering why all my enable/disable links, or similar, are being changed, instead of just the one that was clicked on. You’d think it would just fail, instead, the jQuery selector isn’t scoped to the Backbone view element and instead selects all matching elements in the document.

It’s really not that hard to wrapper the callbacks with the Underscore bind function:

Backbone.View.extend({
events: {
'click a.enable': 'enableHandler',
'click a.disable': 'disableHandler'
},
initialize: function() {
this.model = new Model();
this.model.bind('change', this.render, this);
}
// ...
enableHandler: function(e) {
e.preventDefault();
this.model.save({
enabled: true
}, {
wait: true,
success: _.bind(function() {
this.$('a.enable').hide();
this.$('a.disable').show();
}, this),
error: _.bind(function() {
// ...
}, this)
});
}
// ...
});
view raw Binding.js hosted with ❤ by GitHub

It would be nice if I could remember to do this automatically when writing a callback function. Given that I’m still forgetting to do it after years of programming JavaScript, I don’t hold out much hope that I’ll suddenly start remembering…

Leave a Reply