I've been looking at some patterns for the use of backbone.js, which leverages underscore.js.
In view code, you'll see a sequence like this:
var ThingyItem = Backbone.View.extend({
tagName: "li",
initialize: function() {
_.bindAll(this, 'render', 'elementClass');
this.model.bind("change", this.render);
},
events: {
"change .complete input": "toggleComplete"
},
render: function() {
$(this.el).empty().html(JST['thingys/thingy']({thingy: this.model}));
$(this.el).attr("class", this.elementClass());
return this;
},
elementClass: function() {
if (this.model.isComplete()) {
return "thingy completed-thingy";
} else {
return "thingy";
}
},
toggleComplete: function() {
if (this.model.isComplete() === true) {
this.model.uncomplete({});
} else {
this.model.complete({});
}
return false;
}
});
Let's look at that initialize method:
initialize: function() {
_.bindAll(this, 'render', 'elementClass');
this.model.bind("change", this.render);
}
Here's the documentation for underscore's bindAll method: 'Binds a number of methods on the object, specified by methodNames, to be run in the context of that object whenever they are invoked. Very handy for binding functions that are going to be used as event handlers, which would otherwise be invoked with a fairly useless this. If no methodNames are provided, all of the object's function properties will be bound to it' ( http://documentcloud.github.com/underscore/#bindAll).
In other words, when those methods are called, ensure that "this" is the value of the first parameter (in this case, this). Basically, underscore is helping us get around the problems described in some detail in a blog post from 2008 by Christophe Porteneuve.
However, backbone's "bind" method means: ' Bind a callback function to an object. The callback will be invoked whenever the event (specified by an arbitrary string identifier) is fired. If you have a large number of different events on a page, the convention is to use colons to namespace them: "poll:start", or "change:selection"' ( http://documentcloud.github.com/backbone/#Events-bind).
In other words, when a particular event is fired (in the quoted code, the change event) call (a) certain method(s), here, the render method.
So, be warned. Underscore.js: .bindAll: Ensure that "this" is what you need; backbone.js: bind: associate a function with an event.
The wording is confusion. I think that the underscore.js method is really talking about the binding of this, and the method call should be something like "thisBinding" or some such.
It would be interesting to look at the ECMA spec to the language for these two different ideas.
comments powered by Disqus