问题
This might be a really simple question but I'm having a heck of a time finding an answer.
Using backbone, I have this line:
Person = Backbone.Model.extend();
I then use that in a collection filled from a URL. For the sake of the example, say I have a first and last name, and I want to do something like:
Person = Backbone.Model.extend({
FullName: this.get("firstName") + " " + this.get("lastName")
});
I can call that inside backbone using, for example, People.first().FullName(). But if I pass People.first() to my view and render that in a template, it seems to have no knowledge what FullName is.
How would I add a custom property to a model in Backbone and use that inside a template?
Cheers!
回答1:
Your FullName definition doesn't make any sense so I'm going to assume that you really meant this:
Person = Backbone.Model.extend({
FullName: function() {
return this.get("firstName") + " " + this.get("lastName");
}
});
Usually you'll call toJSON on your models to serialize them for use by a template:
var html = template({ person: person.toJSON() })
The default toJSON simply returns a (shallow) copy of the model's internal attributes. The attributes will, presumably, have both firstName and lastName properties but FullName is a function on the model so it won't be in the attributes.
You could provide your own toJSON:
toJSON: function() {
var j = _(this.attributes).clone();
j.FullName = this.FullName();
return j;
}
and then you'd have a FullName in your template. However, toJSON is also used to serialize the model to send data to the server; your server would end up seeing a FullName and it might get upset about that. You could add another serializer specifically for templates:
// `serialize` is another common name for this
for_template: function() {
var j = this.toJSON();
j.FullName = this.FullName();
return j;
}
and then use that function to supply data for your templates:
var html = template({ person: person.for_template() });
回答2:
I struggled with this for a while too, but I found a solution.
Its covered in a fair amount of depth, including a solution to the issue of toJSON being used to send the server data, in Backbone Computed Properties
回答3:
var Person = Backbone.Model.extend({
parse: function (model) {
model.FullName = model.FirstName + ' ' + model.LastName;
return model;
}
});
回答4:
There is a much more simple method. Include your method inside of your initialize method. When you instantiate your model all of your methods get instantiated as well.
var model = Backbone.Model.extend({
initialize : function(){
this.myCustomMethod = function(){ return 'Something'; };
},
idAttribute : 'id',
urlRoot : ''
});
回答5:
Quite different workaround:
Backbone.Model.extend({
defaults: function() {
this.set('fullName', this.fullName.bind(this))
},
fullName: function() {
return this.get('firstName') + this.get('lastName');
}
});
THis way the 'fullName' function can be called directly on model
model.fullName()
or through get function, allowing it to be called from template:
model.get('fullName')()
来源:https://stackoverflow.com/questions/10779013/backbone-js-how-to-use-a-custom-model-property-in-a-template