2012-06-04 57 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

相關問題