Backbone.js多次触发Collection更改事件

hof*_*max 2 backbone.js backbone-events

在Backbone.js视图之一中,我通过使用更新当前模型(Message的实例)的属性"read" this.model.set( { read: true } );.我确认这个命令只执行一次(我知道"鬼事件").如下所示,我将Collection配置为触发更新事件,其中整个Collection被保存到变量中.不幸的是,该saveToVar函数被调用3次而不是1次!此外,第一次saveToVar被调用,this正确地包含所有集合的模型,而第二次和第三次this只有一个模型,即我进行更新的模型.我一点一点地追踪所有东西,但我不知道为什么会发生这种情况.

window.Message = Backbone.Model.extend({

});

window.MessageCollection = Backbone.Collection.extend({

model: Message,

initialize: function()
{
    this.on("change", this.saveToVar);
},

saveToVar: function(e)
{
    App.Data.Messages = this.toJSON();
    return;
}

});
Run Code Online (Sandbox Code Playgroud)

mu *_*ort 7

在你的jsfiddle,你这样做:

App.Collections.message = new MessageCollection([ ... ]);
var elements = App.Collections.message.where({ id: 4 });
var item = new MessageCollection(elements);
Run Code Online (Sandbox Code Playgroud)

您的where调用将返回message集合中的模型,而不是这些模型的副本,但是返回的模型对象完全相同message.现在您有两个对id: 4模型的引用:

  1. 原来的一个埋在里面App.Collections.message.
  2. 一个在elements[0].

这两个引用都指向同一个对象.然后你添加elements到另一个MessageCollection.现在你有这样的事情:

App.Collections.message.models[3]    item.models[0]
                               |                 |
                               +--> [{id: 4}] <--+
Run Code Online (Sandbox Code Playgroud)

这两个集合将被通知id: 4模型上的更改事件,因为集合会监听其成员上的所有事件:

为方便起见,也会在集合中直接触发在集合中的模型上触发的任何事件.

您的收藏"change"本身会监听事件:

initialize: function()
{
    this.on("change", this.saveToVar);
}
Run Code Online (Sandbox Code Playgroud)

所以当你这样做时:

this.model.set({ read: true });
Run Code Online (Sandbox Code Playgroud)

在您的视图中,两个集合都将收到通知,因为该模型恰好位于两个集合中.

如果我们将您的事件处理程序更改为如下所示:

saveToVar: function() {
    console.log(_(this.models).pluck('cid'));
}
Run Code Online (Sandbox Code Playgroud)

然后你会看到cid两个集合中都出现相同的(Backbone生成的唯一标识符).您还可以为每个集合附加一个随机数,看看你得到了什么saveToVar:http://jsfiddle.net/ambiguous/mJvJJ/1/

你可能不应该在两个集合中有一个模型.你可能不应该有相同模型的两个副本,所以克隆elements[0]在创建之前item也许不是一个好主意.您可能需要重新考虑您的架构.