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

时间:2012-10-24 22:02:22

标签: backbone.js backbone-events

在Backbone.js视图之一中,我使用this.model.set( { read: true } );更新当前模型(Message的实例)的属性“read”。我确认这个命令只执行一次(我知道“鬼事件”)。如下所示,我将Collection配置为触发更新事件,其中整个Collection被保存到变量中。 不幸的是,saveToVar函数被调用3次而不是1次!此外,第一次调用saveToVar时,this正确地包含了所有集合的模型,而第2次和第3次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;
}

});

1 个答案:

答案 0 :(得分: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]中的那个。
  3. 这两个引用都指向同一个对象。然后,您将elements添加到另一个MessageCollection。现在你有这样的事情:

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

    collections listen to all events on their members以来,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生成的唯一标识符)。您还可以在每个集合中附加一个随机数,然后查看saveToVar中的内容:http://jsfiddle.net/ambiguous/mJvJJ/1/

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