2012-06-04 58 views
2

我有一个包含两个对象的父级骨干模型。Backbone.js - 更改模型阵列上的事件不会触发元素更改

(1)主链模型的数组

(2)的字符串

如果我结合到母体,设置字符串的值并触发变化事件,但是调用的属性设置在模型数组中的其中一个模型不会触发父级上的更改事件。

如何解决此问题,以便对数组中的任何模型进行任何更改都会触发父母更改事件?

编辑 - 添加的代码按要求

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 
+0

我们看一些代码。 – fguillen

回答

4

骨干机型不绑定任何东西它们的属性,从而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中也有一个隐藏的bug。默认值被复制到新的模型实例,但副本是浅拷贝,因此您的模型将最终共享对该阵列的相同引用,除非明确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,而不是一个新的空数组,它是专门针对m1http://jsfiddle.net/ambiguous/AraCu/

+0

非常有帮助,谢谢 – asutherland

相关问题