2

在 Backbone.js 视图之一中,我正在使用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;
}

});
4

1 回答 1

7

在您的 jsfiddle 中,您正在执行以下操作:

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

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

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

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

App.Collections.message.models[3]    item.models[0]
                               |                 |
                               +--> [{id: 4}] <--+

这两个集合都将收到有关id: 4模型更改事件的通知,因为集合侦听其成员上的所有事件

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

您的集合本身会监听"change"事件:

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

所以当你这样做时:

this.model.set({ read: true });

在您看来,这两个集合都会收到通知,因为该模型恰好在两个集合中。

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

saveToVar: function() {
    console.log(_(this.models).pluck('cid'));
}

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

您可能不应该在两个系列中拥有一个模型。您可能不应该有两个相同模型的副本,因此elements[0]在创建之前进行克隆item也可能不是一个好主意。您可能需要重新考虑您的架构。

于 2012-10-24T23:26:50.057 回答