Backbone中的计算属性

blo*_*ilk 17 javascript javascript-framework backbone.js

我有一个场景,在客户端上操作的数据以不同于服务器上表示的方式呈现和交互.

请考虑event从服务器返回的以下资源.

{
  "id": 123,
  "start_at": 1331336004906,
  "end_at": 1331337704906
}
Run Code Online (Sandbox Code Playgroud)

以下模板用于编辑:

<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>
Run Code Online (Sandbox Code Playgroud)

我怎么会去治疗start_date,start_time以及duration在我的骨干模型属性,而不将它们发送到服务器?我应该修改.toJSON()吗?

小智 23

我正在使用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});
    }
});
Run Code Online (Sandbox Code Playgroud)


fgu*_*len 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( :) )
      } 
    );
}
Run Code Online (Sandbox Code Playgroud)

当然这打破了一些模式,我可以忍受它,如果你不能,你可以将这个逻辑移到一个Decorator类,就像人们在其他答案中建议的那样.


phi*_*reo 5

你有一些选择:

  • 覆盖toJSON以返回计算的duration

  • duration()在Backbone上创建一个方法Model.唯一的缺点是你必须以不同的方式称呼它(obj.duration()而不是obj.get('duration')).在您的视图中,obj.toJSON()指向您的模板,混合duration属性

  • 使用https://github.com/asciidisco/Backbone.Mutators(或类似)创建派生的getter持续时间


ggo*_*zad 4

您的模型应尽可能与服务器端的模型相符。所以坚持使用start_atend_at。这将大大简化您的sync()操作。

在编辑表单的View上,您可以:

  1. 通过简单的函数计算start_date, start_time,duration并在模板中调用它们。
  2. 转换为start_atend_at提交。