3

この問題は、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 で似たような作業がありました。この問題を回避する方法について他の考えはありますか?

4

2 に答える 2

0

problems完了するたびに属性を再インスタンス化model.fetchし、オブジェクトが異なるため、新しいサイクルをトリガーします。

ネストされたモデルを処理するために私が通常行うこと:

  • Backbone によって処理される属性以外のモデル プロパティを使用する。
  • 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');
    }
});
于 2013-11-08T12:54:26.230 に答える