当我更新到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上触发另一个更改事件。
似乎服务器的所有后续返回都会触发另一个更改事件,更改的属性是“problems”属性。这导致无限递归调用。
问题似乎来自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模型的正确方法吗?我在Backbone 1.1中有类似的工作。关于如何避免这个问题的其他想法?
答案 0 :(得分:0)
在获取和保存时调用parse(根据主干文档),这可能会导致无限循环。我不认为解析函数是创建新的ProblemsList子集合的正确位置,而是在模型的初始化函数中执行。
答案 1 :(得分:0)
每次problems
完成时,您都会重新验证model.fetch
属性,对象不同,从而触发新的循环。
我通常用来处理嵌套模型:
initialize
函数set
函数中reset
或parse
此对象并返回省略设置数据的响应这样的事情:
var ProblemSet = Backbone.Model.extend({
defaults: {
name: "",
open_date: "",
due_date: ""
},
initialize: function (opts) {
var pbs = (opts && opts.problems) ? opts.problems : [];
this.problems = new ProblemList(pbs);
},
parse: function (response) {
response.name = response.set_id;
if (response.problems)
this.problems.set(response.problems);
return _.omit(response, 'problems');
}
});