主干.js - 模型数组上的更改事件不会在元素更改时触发



我有一个包含两个对象的父主干模型。

(1) 一系列骨干模型

(2) 字符串

如果我绑定到父项,设置字符串的值确实会触发更改事件,但是对模型数组中某个模型的属性调用 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

主干模型不会将任何东西绑定到它们的属性上,因此foo无法知道你正在背后更改它的一个属性。因此,当您执行此操作时:

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

你实际上根本没有改变foo,你所做的只是直接改变了foo的属性之一。模型的属性可以是任何内容,模型只是将它们视为不透明的斑点。对于这样的事情,你会遇到类似的问题:

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

在这两种情况下,您都是通过引用而不是通过模型的接口直接更改模型的属性。

另一方面,集合确实侦听其模型上的事件。集合是模型的集合,因此它们希望其成员成为模型并相应地运行。

如果您希望包含的模型传播'change'事件,则必须自己执行此操作,例如,重写手动绑定更改处理程序以传播事件的set。还可以使用内部集合而不是数组来更轻松地传播事件。


您的defaults中还有一个隐藏的错误。默认值将复制到新的模型实例,但副本是浅拷贝,因此您的模型最终将共享对数组的相同引用,除非执行显式set来替换引用。例如,这个:

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'));

将在控制台中放置两个['pancakes'],因为m1.get('a')将返回M.prototype.defaults.a而不是特定于m1的新空数组:http://jsfiddle.net/ambiguous/AraCu/

最新更新