对Backbone.js模型进行“局部”更改沉默

Make Backbone.js Model change "partially" silent?

本文关键字:局部 沉默 Backbone js 模型      更新时间:2023-09-26

当我的"chartModel"改变时,我想更新"globalModel"。

chartModel.bind("change", updateGlobalModel);
updateGlobalModel(){
  globalModel.set(obj)
}

反之亦然,我希望我的chartModel在globalModel更改时更新。

globalModel.bind("change", updateChartModel);
updateChartModel(){
  chartModel.set(obj)
}

这会在设置globalModel时导致一个反馈循环。我可以通过设置{silent:true}来防止这种情况。

但是问题来了。我有另一个依赖于更改事件的模型:

globalModel.bind("change", updateOtherModel);

我如何提醒这个模型的变化,而不是前一个(以避免反馈循环)?

更新:
现在,我决定为每个set调用生成一个特定的ID:

set : function(attrs, options) { 
        if(!("setID" in attrs)){
            attrs.setID = myApp.utils.uniqueID(); //newDate.getTime();
        }
        Backbone.Model.prototype.set.call(this, attrs, options);
    },

这样,我就可以在应用程序的任何地方生成一个"setID"属性。如果从模型中获取内容时setID仍然相同,我知道可能存在反馈循环的风险。

晚做总比不做好。

最简单的方法是使用标志。例如,当在globalModel中设置某些内容时,您还可以更改模型上的属性以指示您已经更改了某些内容。然后可以在updateChartModel中验证该标志的值。例如:

chartModel。bind("改变",updateGlobalModel);

function updateGlobalModel() {
    if (!flag) {
        globalModel.set(obj);
        flag = true;
    }
}

可能和你最后用setID做的非常相似。顺便说一句,下划线有一个内置的uniqueId函数。

你还可以做一件更简洁的事情,就是在你的set调用中传递一个选项。

chartModel.set(obj, { notify : false });

是的,你可以传递任何你想要的选项,你不仅仅局限于{ silent : true }。有关更多信息,请参阅github上的讨论。然后,检查是否存在这样的属性,在这里处理更改事件,如下所示:

function updateGlobalModel(model, options){
    // explicitly check for false since it will otherwise be undefined and falsy
    // you could reverse it.. but I find this simpler
    if (options.notify !== false) {
        globalModel.set(obj)
    }
}

,在第三个模型(和其他模型)中,您可以放弃此检查。

最后一个选择当然是看你的设计。如果这两个模型是如此紧密相关,它们必须彼此保持同步,那么合并它们的功能可能是有意义的。或者,您可以将公共功能分离出来。

我的知识是有限的,所以也许我不应该回答,但我会尝试在创建指向您想要更新的"其他"模型的chartModel时传递引用。然后在updateChartModel()上触发一个事件,并确保你的"other"模型绑定在该事件上。

我的问题是:沉默对象是否使所有事件静音?或者只是模型相关的?如果所有的事件都是静音的,这显然是行不通的。