2

Backbone.jsビューの1つで、を使用して現在のモデル(メッセージのインスタンス)の属性「読み取り」を更新していますthis.model.set( { read: true } );。このコマンドが1回だけ実行されることを確認しました(「ゴーストイベント」について知っています)。以下に示すように、コレクション全体が変数に保存される更新イベントを発生させるようにコレクションを構成しました。残念ながら、saveToVar関数は1回ではなく3回呼び出されます。また、1回目saveToVarthis、コレクションのすべてのモデルで正しく構成されていますが、2回目と3回目thisは、更新を行ったモデルの1つだけです。私はすべてを少しずつ追跡しましたが、なぜこれが起こるのか分かりません。

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これらのモデルのコピーではなく、にあるのとまったく同じモデルオブジェクトを返しますmessageid: 4これで、モデルへの2つの参照があります。

  1. 中に埋められたオリジナルのものApp.Collections.message
  2. の1つ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/

おそらく、2つのコレクションに1つのモデルを含めるべきではありません。同じモデルのコピーが2つあるべきではないので、作成elements[0]する前にクローンを作成するitemこともお勧めできません。アーキテクチャを再考する必要があるかもしれません。

于 2012-10-24T23:26:50.057 に答える