backbone.js如何:当设置一个属性时,自动更新另一个

时间:2013-03-20 17:40:38

标签: backbone.js backbone-events

人们,对以下的最佳做法和API细节感到疑惑 情况。

假设我们有一个模型选择:

Selection = Backbone.Model.extend({
  defaults: {
    value : null,
    related: null,
    other: null,
    stuff: null
  }
}

如果我们改变'价值'而不设置'相关',那么我们想要 将'related'设置为null ---级联更新的排序。

还有其他听众需要查看更新后的值 当'价值'改变时'相关'。所以,我们要保证这一点 当调用任何这些侦听器时,会更新“相关” 相应

所以我们也许可以选择模型本身 '更改:值',并在必要时设置'相关'。但是Backbone 保证在任何其他监听器之前调用该监听器 “变化:价值”?同样,它是否保证合格的事件会 在通用事件之前触发,因此在“更改”之前“更改:值”?

依靠事件系统来做这件事看起来很脆弱所以我们看了 一些钩子。我们能找到的最接近的是_validate / validate 方法,我们可以在我们的Selection模型中添加如下内容:

// Use _validate as a "before-set call" to set 'related' if necessary
_validate: function(attrs, options) {
  if (!_.has(attrs, 'related') && _.has(attrs, 'value') && 
      !_.isEqual(attrs.value, this.attributes.value)) {
    attrs.related = null;
  }
  return true;
}

当然,这违背了“验证”所暗示的语义。

非常感谢任何指导。

2 个答案:

答案 0 :(得分:0)

由于Backbone.Model set方法支持传递多个属性,我建议覆盖它。

有些事情(很抱歉使用CoffeeScript - super在这里有点直截了当):

class myView extends Backbone.View
   set: (attributes, options) ->
       if attributes.value == "something"
             attributes.related = null
             #set all the cascade updates in the attributes object
       super(attributes,options)

答案 1 :(得分:0)

您可以覆盖Model.set并包含您的测试。

沿着这些方向徘徊:

var Selection = Backbone.Model.extend({
    defaults: {
        value : null,
        related: null,
        other: null,
        stuff: null
    },

    set: function(key, val, options) {
        var attrs;

        //nothing to set
        if (key == null) return this;

        if (typeof key === 'object') {
           // setting a hash
            attrs = key;
            options = val;
        } else {
           // setting a key-value pair
            (attrs = {})[key] = val;
        }

        // set related values
        if (!_.has(attrs, 'related') && _.has(attrs, 'value') &&  
                  !_.isEqual(attrs.value, this.attributes.value)) {
            attrs.related = null;
        }

        // call the parent
        Backbone.Model.prototype.set.call(this, attrs, options);
    }
});

小提琴http://jsfiddle.net/nikoshr/KSHwc/