I\'m using Backbone.js for the first time, and liking it so far. One thing I can\'t work out at the moment in dynamic attributes of models. For example, say I have a Person
I would think of attributes as the raw materials used by a model to provide answers to callers that ask the questions. I actually don't like having callers know too much about the internal attribute structure. Its an implementation detail. What if this structure changes?
So my answer would be: don't do it.
Create a method as you've done and hide the implementation details. Its much cleaner code and survives implementation changes.
Would this be simpler?
var Person = Backbone.Model.extend({
get: function (attr) {
if (typeof this[attr] == 'function')
{
return this[attr]();
}
return Backbone.Model.prototype.get.call(this, attr);
}
});
This way you could also override existing attributes with functions. What do you think?
The actual properties used by Model.get are stored in the attribute property. You could do something like this:
// function to cross-browser add a property to an object
function addProperty(object, label, getter, setter) {
if (object.defineProperty){
object.defineProperty(object, label, {getter: getter, setter: setter})
}
else {
object.__defineGetter__(label, getter)
object.__defineSetter__(label, setter)
}
}
// inside the initializer of your model, add a property to the attribute object
var Person = Backbone.Model.extend({
initialize: function(attr, options) {
var t = this;
...
addProperty(this.attributes, 'fullName',
function() {return t.get('firstName') + ' ' + t.get('surname'),
function(val) {...}
)
}
})
This will allow you to do person.get('fullName') as you requested.
Edit: To be clear, I agree with Bill's answer below. Shouldn't really be dinking around with the internal implementation of backbone.js. Especially since this is incomplete...what about escape() instead of get()? And the setter is more complex, as it does validation, change notification, etc...now I'm sorry I posted this :)