问题:当存在需要以特定方式存储的属性时,初始化backbone.js模型的正确方法是什么?我是否需要映射不需要任何特殊格式的属性?我以为backbone.js做了某种自动映射。
示例:
var MyModel = Backbone.Model.extend({
initialize: function (options) {
// These attributes need to be stored in a different format
// Dates
this.startYear = new Date(options.startTime).getFullYear();
// Rounding numbers
this.wholeNumber = Math.Round(options.numberWithDecimals);
// Storing empty strings as nulls
if (options.fullName == null || options.fullName == "") {
this.fullName == null;
} else {
this.fullName = options.fullName;
}
// These are fine as they are
this.fieldA = options.fieldA;
this.fieldB = options.fieldB;
this.fieldC = options.fieldC;
},
});
答案 0 :(得分:12)
首先,您必须区分attributes
和instance variables
。
属性:恕我直言,它应该是普通对象,如String或Integer。他们通过REST API在客户端和服务器周围旅行。它们是通过Model.get() / Model.set()方法操纵的。它们通过Model.toJSON()发送到服务器(也可以使用相同的template
方法发送到.toJSON()
。如果它们以某种方式更改,则 Backbone事件< / em>被触发。您可以自定义此attributes
的初始化操作服务器端JSON信息,然后将其发送到模型,覆盖{muistooshort建议的Model.parse()方法。
实例变量 :( this.myAttribute
事物)它们可以是复杂的对象。不会在更改中触发任何隐含事件,并且不会在save
和update
调用中将它们发送到服务器,并且以标准方式,它们不会发送到模板
在你的例子中,你没有存储任何复杂的对象,如果你不担心你的模型会向服务器发送比从服务器收到的更多属性,你可以去找@muistooshort建议:
// code no tested
var MyModel = Backbone.Model.extend({
parse: function(resp, xhr) {
resp.startYear = new Date( resp.startTime ).getFullYear();
resp.wholeNumber = Math.Round( resp.numberWithDecimals );
if( resp.fullName == "" ) resp.fullName == null;
return resp;
},
});
请记住,这些是属性,您必须以这种方式访问它们my_model.get( "startYear" )
此解决方案的唯一问题是,如果原始属性发生更改,派生属性将不会更新。所以你可以使用另一个实现:
// code no tested
var MyModel = Backbone.Model.extend({
initialize: function(){
this.updateAttributes();
this.on( "change", this.updateAttributes, this );
},
updateAttributes: function() {
this.set( "startYear", new Date( this.get( "startTime" ) ).getFullYear() );
this.set( "wholeNumber", Math.Round( this.get( "numberWithDecimals" ) ) );
if( this.get( "fullName" ) == "" ) this.set( "fullName", null );
},
});
正如@TomTu建议,如果只需要提供 onlive属性来提供模板,那么装饰器是最佳解决方案:https://stackoverflow.com/a/9687672/316700
答案 1 :(得分:2)
如果您只需要在模板中使用辅助值,则可以使用覆盖的toJSON
方法计算它们,这将添加在视图中表示模型时可能需要的所有额外属性。
As the documentation for Backbone.js says:
model.toJSON()
返回JSON字符串化的模型属性的副本。 这可用于持久性,序列化或扩充 在交给视图之前。 ...
正如我在评论中提到的另一个答案 - 在parse
方法中更改模型将导致创建开销,每次模型保存时都会发送到服务器,应该被认为是草率和糟糕的实践
由于模型初始化没有以类似于视图的方式将选项绑定到模型实例,因此您始终可以在初始化方法中执行此操作,然后根据需要引用覆盖的toJSON方法中的选项无论你想达到什么目的
答案 2 :(得分:0)
已经回答,但只是有点整洁:
var contact = Backbone.Model.extend({
parse: function (response) {
response.newAttribute = response.alreadyProvidedAttribute;
return response;
}
});