【发布时间】:2013-11-19 23:56:20
【问题描述】:
这个问题似乎是在我更新到 Backbone 1.1 时出现的。我有一个嵌套的 Backbone 模型:
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
});
我最初加载了一个 ProblemSetList,它是我页面中的 ProblemSet 模型的集合。对任何 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);
}
}
对问题属性的比较从 _.isEqual() 中返回 false,因此会触发一个更改事件。
我的问题是:这是做嵌套主干模型的正确方法吗?我在 Backbone 1.1 中有类似的工作。关于如何避免此问题的其他想法?
【问题讨论】:
-
我了解到您已将
save绑定到模型的change事件? -
是的。就像:problemSets.on("change",function(_set){ _set.save();});
-
我最近认为骨干 1.1 不是问题,而是强调它也更新到 1.5.2,并且对带有对象的 _.isEqual 函数进行了一些更改。
-
更多探索使我得出以下结论:我上面引用的 Backbone.js 代码正在返回一个更改变量,这意味着当前对象与刚刚从服务器发送的对象之间存在差异。似乎原因是新对象的ID与旧对象不同;我在想,因为他们通过了 parse 命令(上面列出)并创建了一个新的 ProblemList。一对新的问题可能是:对于像这样的嵌套模型,我应该不创建一个新的 ProblemList 集合(并保留旧的 id)还是有其他方法?
标签: backbone.js