3

这个问题似乎只是在我更新到 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 中有类似的工作。关于如何继续避免这个问题的其他想法?

4

2 回答 2

0

problems每次完成时,您都会重新实例化您的属性model.fetch,对象是不同的,因此会触发一个新的循环。

我通常处理嵌套模型的方法:

  • 在 Backbone 处理的属性之外使用模型属性,
  • initialize在函数中实例化它,
  • setreset父函数中的此对象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');
    }
});
于 2013-11-08T12:54:26.230 回答
0

parse 在获取和保存时被调用(根据主干文档),这可能会导致您的无限循环。我不认为 parse 函数是创建新 ProblemsList 子集合的正确位置,而是在模型的初始化函数中进行。

于 2013-11-08T10:53:44.897 回答