Backbone中的计算属性

Computed properties in Backbone

本文关键字:属性 计算 Backbone      更新时间:2023-09-26

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

考虑从服务器返回的以下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发送到服务器的情况下,如何将它们视为骨干模型中的属性?我应该修改.toJSON()吗?

我使用initialize()函数与更改事件监听器的组合来更新派生属性。这个想法首先是在模型初始化时计算属性,其次是让模型倾听自己的变化并相应地更新属性。

我的解决方案大致如下:

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});
    }
});

我们非常习惯于将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类,就像人们在其他答案中建议的那样。

您有一些选项:

  • 覆盖toJSON以返回计算的duration

  • 在主干Model上创建一个duration()方法。唯一的缺点是你必须用不同的方式来称呼它(obj.duration()而不是obj.get('duration'))。在将obj.toJSON()交给模板的视图中,混合duration属性

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

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

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

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