Backbone中的计算属性

时间:2012-03-09 23:40:05

标签: javascript backbone.js javascript-framework

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

考虑从服务器返回的以下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_datestart_timeduration作为我的Backbone模型中的属性进行处理而不将其发送到服务器?我应该修改.toJSON()吗?

4 个答案:

答案 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_atend_at。这将大大简化您的sync()操作。

在编辑表单的查看中,您可以:

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