子模型更改事件不会传播到主干中的父模型

时间:2011-08-24 22:05:13

标签: javascript backbone.js

所以我将这个子模型关联到我视图的1个列表项,当我编辑这个模型时,视图重新正确呈现。

但是当完整的列表模型发生变化时,我还得到了父做的其他事情,并且更改事件没有在aprent级别触发,这很奇怪,

如果我手动触发model.change(),我会看到从子模型更新的内容(意味着父模型已有效更改)。

是否有自动方式将更改事件传播到父模型?

2 个答案:

答案 0 :(得分:4)

您的“父母”是子模型所属的集合吗?如果是,则只要子模型的属性发生更改,集合就会收到更改通知。这是一个演示模型/集合更改事件的示例:

var Product = Backbone.Model.extend({});
var Products = Backbone.Collection.extend({
    model: Product
});

var ProductsView = Backbone.View.extend({
    initialize: function () {
        this.collection.bind('change', this.onProductChange, this);
    },
    onProductChange: function (product) {
        console.log('product with ID ' + product.get('id') + ' changed to ' + product.get('name'));
    }
});

var products = new Products([{ id: 1, name: 'Book' }, { id: 2, name: 'Toy' }, { id: 3, name: 'Shirt'}]);
new ProductsView({collection:products});

products.get(1).set({ name: 'TV' }); // console: product with ID 1 changed to TV

另一方面,如果您的“父母”不是您的子模型的集合,并且只有父/子关系,那么Backbone无法知道这种关系,因此您需要触发更改每当孩子改变时父母的事件。例如:

    var Parent = Backbone.Model.extend({
        includeChild: function (child) {
            child.bind('change', this.onChildChange, this);
        },
        onChildChange: function (child) {
            console.log('Child with name ' + child.get('name') + ' changed.');
        }
    });
    var Child = Backbone.Model.extend({});

    var parent = new Parent();
    var child = new Child({ name: 'Bob', parent: parent });
    parent.includeChild(child);

    child.set({name: 'Joe'}); // console: Child with name Joe changed.

以下是Backbone事件的完整列表:http://documentcloud.github.com/backbone/#FAQ-events

答案 1 :(得分:1)

我喜欢JohnnyO的解决方案,并且我已经使用他的解决方案在我的应用程序中创建了一个通用的“SuperModel”类。以下是此类的Coffeescript版本,它允许使用父级注册子模型并自动传播所有事件:

class Model.SuperModel extends Backbone.Model

  includeChild: (id, model) ->
    @set id, model
    @listenTo model, 'all', @trigger

就是这样。使用它很容易:

parent = new Model.SuperModel()
parent.includeChild('child', new Backbone.Model())

view = new Backbone.View()
view.listenTo(parent, 'change', -> console.log "parent changed!")

parent.get('child').set('foo', 'bar')

这将打印出“父改变”,正如您所期望的那样。

相关问题