Dexygen
Dexygen

Reputation: 12561

Avoiding need to call _.bindAll in backbone

From my reading it appears that when extending a Backbone.js class such as Model, a fairly common pattern is to call _.bindAll in the constructor as follows (see https://raw.github.com/eschwartz/backbone.googlemaps/master/lib/backbone.googlemaps.js):

GoogleMaps.Location = Backbone.Model.extend({
  constructor: function() {
    _.bindAll(this, 'select', 'deselect', 'toggleSelect', 'getLatLng', 'getLatlng');
    // etcetera

I do understand why this gets done, however the need for explicitly passing method names to _.bindAll seems to be a maintenance issue -- if you add new methods, you have to remember add them as an argument to _.bindAll as well.

Earlier today I posted a somewhat verbose solution to this here: https://stackoverflow.com/a/17977852/34806

However, shouldn't the following simple technique altogether avoid the need to call _.bindAll? And that is, instead of the customary way of assigning "custom" methods, to instead attach them all to "this" within the constructor:

constructor: function() {
    this.foo = function() {};
    this.bar = function() {};
}

Are there any downsides to this technique?

Upvotes: 0

Views: 206

Answers (2)

Jack
Jack

Reputation: 10993

This that you need to explicitly pass in the names of the methods to _BindAll you want to bind is actually a pretty recent change as of underscore.js 1.5.0 - 7/6/13, if you look at the change log for that release you'll see the following reason given for that change

Removed the ability to call _.bindAll with no method name arguments. It's pretty much always wiser to white-list the names of the methods you'd like to bind.

That said it's probably better to do as Esailija says and just bind it just in time by utilizing the optional third parameter which keeps the bindings more localized.

Upvotes: 0

Esailija
Esailija

Reputation: 140230

Your technique doesn't work, you still need to bind those methods like any other. Or use something like var this = self but then those methods cannot be used in sub-classes or anywhere else for that matter.

Just get rid of the bindAll altogether and bind just in time when you need it, e.g. when passing a method as a callback somewhere. It should be far easier on the maintenance because the chore is localized. Forgetting to bind when passing a method as a callback should eventually feel wrong like forgetting to use var.

Upvotes: 1

Related Questions