【问题标题】:Computed properties in BackboneBackbone 中的计算属性
【发布时间】:2012-03-27 09:34:07
【问题描述】:

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

考虑以下从服务器返回的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()吗?

【问题讨论】:

标签: javascript backbone.js javascript-framework


【解决方案1】:

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

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

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

【讨论】:

  • 把这个放在 View 中不是会导致大量冗余代码吗?我将在整个网站上使用相同的虚拟属性,其中一个事件有多个显示它的视图。
  • 不需要冗余。创建一个基本视图并扩展它。
  • 好电话!我也认为装饰器模式可以解决这个问题。
  • 当然,如果复杂性足以证明伪继承是合理的,那么装饰器听起来是个不错的选择!
【解决方案2】:

我们非常习惯发送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 类,正如人们在其他答案中所建议的那样。

【讨论】:

    【解决方案3】:

    你有一些选择:

    • 覆盖toJSON 以返回计算得到的duration

    • 在主干Model 上创建一个duration() 方法。唯一的缺点是您必须以不同的方式调用它(obj.duration() 而不是obj.get('duration'))。在您看来,将obj.toJSON() 传递给您的模板,混合duration 属性

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

    【讨论】:

    • 谢谢。我通常采用被描述的方法,但我不知道 Mutators:它看起来非常有用并且做得很好。
    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 2020-12-01
      • 2020-02-05
      • 2014-01-23
      • 2017-08-23
      • 1970-01-01
      • 2023-03-04
      • 1970-01-01
      • 2022-01-05
      • 2020-05-17
      相关资源
      最近更新 更多