2

2つのオブジェクトを含む親バックボーンモデルがあります。

(1)バックボーンモデルの配列

(2)文字列

親にバインドする場合、文字列の値を設定すると変更イベントがトリガーされますが、モデルの配列内のモデルの1つの属性でsetを呼び出すと、親で変更イベントがトリガーされません。

配列内のモデルのいずれかを変更すると、親の変更イベントがトリガーされるように、これを修正するにはどうすればよいですか?

編集-リクエストによりコードを追加

var myModel = Backbone.Model.extend(
  {
    defaults : {
      models : [],
      aString: 'foobar'
    }
  }
);
var foo = new myModel();
var arrayElement = Backbone.Model.extend({x: 7});
var arrayElement1 = new arrayElement({x: 7});
foo.set('models', [arrayElement1]);
foo.bind('change', function() { console.log('changed!')});
arrayElement1.set('x', 10);  //Does not trigger console log
foo.set('aString', 'barfoo'); //Does trigger console log
4

1 に答える 1

4

バックボーンモデルは属性に何もバインドしないため、foo背後にある属性の1つを変更していることを知る方法はありません。したがって、これを行うと:

foo.set('models', [some_other_model]);
some_other_model.set(...);

実際にfooはまったく変更していません。行ったのは、fooの属性の1つを直接変更することだけです。モデルの属性は何でもかまいません。モデルはそれらを不透明なブロブとして扱います。次のような問題でも同様の問題が発生します。

o = { a: 'b' };
m.set('p', o);
o.a = 'c';

どちらの場合も、モデルのインターフェースではなく、参照を介してモデルの属性を直接変更します。

一方、コレクションはモデルのイベントをリッスンします。コレクションはモデルのコレクションであるため、メンバーがモデルであり、それに応じて動作することを期待しています。

含まれているモデルでイベントを伝播する場合は、変更ハンドラーを手動でバインドしてイベントを伝播するよう'change'にオーバーライドすることで、自分で行う必要があります。set配列の代わりに内部コレクションを使用して、イベントの伝播を容易にすることもできます。


また、に隠れたバグがありますdefaultssetデフォルトは新しいモデルインスタンスにコピーされますが、コピーは浅いコピーであるため、参照を置き換えるために明示的に行われない限り、モデルは配列への同じ参照を共有することになります。たとえば、これは次のとおりです。

var M = Backbone.Model.extend({
    defaults: {
      a: []
    }
});
var m1 = new M();
m1.get('a').push('pancakes');
console.log(M.prototype.defaults.a);
var m2 = new M();
console.log(m2.get('a'));

http://jsfiddle.net/ambiguous/AraCu/ </ p> に固有の新しい空の配列ではなく、が返される['pancakes']ため、コンソールに2つ配置されます。m1.get('a')M.prototype.defaults.am1

于 2012-06-04T18:27:25.083 に答える