我有一个场景,在客户端上操作的数据以不同于服务器上显示的方式呈现和交互。
考虑从服务器返回的以下event
资源。
{
"id": 123,
"start_at": 1331336004906,
"end_at": 1331337704906
}
以下用于编辑的模板:
<form>
<!-- Notice how date and time are separated in the interface -->
<input type="text" name="start_date" value="{{start_date}}" />
<input type="text" name="start_time" value="{{start_time}}" />
<!-- Instead of asking for an end date/time, we ask for the duration -->
<input type="text" name="duration" value="{{duration}}" />
<input type="submit" />
</form>
如何将start_date
,start_time
和duration
作为我的Backbone模型中的属性进行处理而不将其发送到服务器?我应该修改.toJSON()
吗?
答案 0 :(得分:22)
我正在使用initialize()函数和change事件侦听器的组合来更新派生属性。这个想法首先计算模型初始化的属性,然后让模型听取自己的变化并相应地更新属性。
我的解决方案大致如下:
MyModel: Backbone.Model.extend({
initialize: function() {
this.updateDerivedAttributes();
this.on('change:start_at', this.updateDerivedAttributes, this);
},
updateDerivedAttributes: function() {
this.set({
start_date: Utils.dateFromDate( this.get( "start_at" ) ),
start_time: Utils.timeFromDate( this.get( "start_at" ) ),
duration: Utils.youGetTheIdea()
}, {silent:true});
}
});
答案 1 :(得分:6)
我们非常习惯将model.toJSON()
发送到提供模板。这种方法非常难以覆盖,因为它被其他组件使用。
但我们可以使用自定义model.toJSONDecorated()
方法提供模板,如下所示:
# in your Backbone.Model
toJSONDecorated: function(){
return
_.extend(
this.toJSON(),
{
start_date : Utils.dateFromDate( this.get( "start_at" ) ),
start_time : Utils.timeFromDate( this.get( "start_at" ) ),
duration : Utils.youGetTheIdea( :) )
}
);
}
当然这打破了一些模式,我可以忍受它,如果你不能,你可以将这个逻辑移到Decorator
课程,正如人们在其他答案中所建议的那样。
答案 2 :(得分:5)
你有一些选择:
覆盖toJSON
以返回计算出的duration
在Backbone duration()
上创建Model
方法。唯一的缺点就是必须以不同方式调用它(obj.duration()
而不是obj.get('duration')
)。在您看来,将obj.toJSON()
放到模板中,混合使用duration
属性
使用https://github.com/asciidisco/Backbone.Mutators(或类似内容)为持续时间创建派生的getter
答案 3 :(得分:4)
您的模型应尽可能与服务器端相对应。坚持使用start_at
和end_at
。这将大大简化您的sync()
操作。
在编辑表单的查看中,您可以:
start_date
,start_time
,duration
并在模板中调用它们。start_at
和end_at
。