この問題は、Backbone 1.1 にアップデートしているときに発生したようです。ネストされたバックボーン モデルがあります。
var ProblemSet = Backbone.Model.extend({
defaults: {
name: "",
open_date: "",
due_date: ""},
parse: function (response) {
response.name = response.set_id;
response.problems = new ProblemList(response.problems);
return response;
}
});
var ProblemList = Backbone.Collection.extend({
model: Problem
});
最初に、ページ内の ProblemSet モデルのコレクションである ProblemSetList を読み込みます。ProblemSet の open_date または due_date フィールドへの変更は、最初にサーバーに移動してそのプロパティを更新してから戻ります。これにより、ProblemSet で別の変更イベントが発生します。
サーバーからのすべての後続のリターンが別の変更イベントを発生させ、変更された属性が「問題」属性であるように見えます。これにより、無限の再帰呼び出しが発生します。
問題は、Backbone.Model の set メソッドの一部にあるようです (コードは 339 行目からここにリストされています)。
// For each `set` attribute, update or delete the current value.
for (attr in attrs) {
val = attrs[attr];
if (!_.isEqual(current[attr], val)) changes.push(attr);
if (!_.isEqual(prev[attr], val)) {
this.changed[attr] = val;
} else {
delete this.changed[attr];
}
unset ? delete current[attr] : current[attr] = val;
}
// Trigger all relevant attribute changes.
if (!silent) {
if (changes.length) this._pending = true;
for (var i = 0, l = changes.length; i < l; i++) {
this.trigger('change:' + changes[i], this, current[changes[i]], options);
}
}
problems 属性の比較では、_.isEqual() から false が返されるため、change イベントが発生します。
私の質問は: これは入れ子になったバックボーン モデルを行う正しい方法ですか? Backbone 1.1 で似たような作業がありました。この問題を回避する方法について他の考えはありますか?