I am building a small Backbone.js application and added some custom getters to one of the models (the name getter returns a concatenated first- and last name for example):
PersonModel = Backbone.Model.extend({
get: function (attr) {
if (typeof this[attr] == 'function') {
return this[attr]();
}
return Backbone.Model.prototype.get.call(this, attr);
},
name: function() {
return firstName + " " + lastName;
}
})
I can now use person.get("name")
to retrieve the name, nice. However, when I call toJSON
on the the model these values aren't included (and I suppose that makes sense). Problem is I use this to render my views:
this.template({people: this.collection.toJSON()});
What's the best way to do this in Backbone.js? Manually creating the JSON with the overwritten getters?
Thanks!
You could provide your own toJSON
method on PersonModel:
toJSON: function() {
var attr = Backbone.Model.prototype.toJSON.call(this);
attr.name = this.name();
return attr;
}
The collection toJSON just calls toJSON
on each model:
// The JSON representation of a Collection is an array of the
// models' attributes.
toJSON : function() {
return this.map(function(model){ return model.toJSON(); });
},
so adding your own toJSON
to your model should work.
You could also add name
as a real attribute and then adjust your model's validate
method to update name
if firstName
or lastName
changes and to ignore any direct attempts to change name
or complain about "an attempt to edit a read-only attribute" when someone tries to pass a name
change to set
. There's nothing that says that validate
can't change the attribute object that it is given so you could be given {firstName: 'x'}
and change it to {firstName: 'x', name: 'x ' + this.get('lastName')}
before validate
returns. This would be a bit of an abuse of validate
but there is no explicit prohibition against validate
altering the attribute set and it is the only hook you have. I suppose you could have the model listen to change events on its own firstName
and lastName
and then trigger a set({name: ...})
but then you could have event ordering problems if someone else is watching only the first and last names.