【问题标题】:Backbone.js - Change Event on Array of Models Doesn't Trigger On Element ChangeBackbone.js - 模型数组上的更改事件不会在元素更改时触发
【发布时间】:2012-06-05 02:47:59
【问题描述】:

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

(1) Backbone 模型数组

(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

【问题讨论】:

    标签: javascript backbone.js


    【解决方案1】:

    主干模型不会将任何内容绑定到它们的属性,因此foo 无法知道您正在更改其背后的属性之一。所以,当你这样做时:

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

    您实际上根本没有更改foo,您所做的只是直接更改了foo 的属性之一。模型的属性可以是任何东西,模型只是将它们视为不透明的 blob。你会遇到类似的问题:

    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/

    【讨论】:

      猜你喜欢
      • 2012-01-19
      • 1970-01-01
      • 1970-01-01
      • 2014-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多