Using a Backbone Model with Handlebars
A Backbone model’s property has to be accessed with the get(property)
method.
var myObj = Backbone.Model.extend({ ... });
//don't do this
console.log(myObj.myProp);
//do this instead
console.log(myObj.get('myProp'));
If you’re trying to pass this object to a Handlebars.js, things start to get messy. If you’ve got a template like this
var myTemplate = Handlebars.compile("Property: ");
console.log(myTemplate(myObj));
Handlebars won’t find the property, and nothing will be displayed. There’s a well-known workaround to this though, which is to convert the Backbone Model into JSON
console.log(myTemplate(myObj.toJSON()));
However this isn’t as readable as I’d prefer. If your collection gets really big, it can make your application slow, and in situations where you’ve got a Backbone Collection of Models, it doesn’t even work. A. Matias Quezada has a better solution, which is to tell Handlebars, “hey, if it’s a Model, use the get method”:
Handlebars.JavaScriptCompiler.prototype.nameLookup = function (
parent,
name,
type
) {
var result =
"(" +
parent +
" instanceof Backbone.Model ? " +
parent +
'.get("' +
name +
'") : ' +
parent;
if (/^[0-9]+$/.test(name)) {
return result + "[" + name + "])";
} else if (
Handlebars.JavaScriptCompiler.isValidJavaScriptVariableName(name)
) {
return result + "." + name + ")";
} else {
return result + "['" + name + "'])";
}
};
That’s it. If you run that somewhere before your Template runs, Handlebars will be able to find the Backbone Model’s property.
In writing this post, I also came across Thorax.js, which probably also fixes this problem.