javascript - Backbone.js - Change Event on Array of Models Doesn't Trigger On Element Change -
i have parent backbone model contains 2 objects.
(1) array of backbone models
(2) string
if bind parent, setting value of string trigger change event, calling set on attribute of 1 of models in array of models not trigger change event on parent.
how fix change of models in array triggers parents change event?
edit -- added code request
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
backbone models don't bind attributes foo has no way of knowing changing 1 of attributes behind back. so, when this:
foo.set('models', [some_other_model]); some_other_model.set(...); you haven't changed foo @ all, you've done changed 1 of foo's attributes directly. model's attributes can anything, model treats them opaque blobs. you'll have similar problems this:
o = { a: 'b' }; m.set('p', o); o.a = 'c'; in both cases, you're directly changing model's attribute through reference rather through model's interface.
collections, on other hand, listen events on models. collections collections of models expect members models , behave accordingly.
if want contained model propagate 'change' events you'll have by, perhaps, overriding set manually bind change handlers propagate events. use internal collection instead of array make propagating events easier.
you have hidden bug in defaults. defaults copied new model instances copy shallow copy models end sharing same reference array unless explicit set done replace reference. example, this:
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')); will put 2 ['pancakes'] in console because m1.get('a') return m.prototype.defaults.a rather new empty array specific m1: http://jsfiddle.net/ambiguous/aracu/
Comments
Post a Comment