Как я могу "раздуть" события на вложенных коллекциях Backbone?

У меня есть приложение Backbone, которое использует вложенные коллекции (по крайней мере, так, как я думаю, они вызваны).

В моем конкретном случае есть вкладки и subtabs, а каждая вкладка (модель) содержит коллекцию подзаголовка (модели).

Для тех, кто более знаком с кодом, я напишу ниже свои модели и коллекции и как вложенные вложенные элементы внутри модели вкладок:

// Subtab Model
var Subtab = Backbone.Model.extend({
    defaults: { label: undefined }
});

// Subtabs Collection
var Subtabs = Backbone.Collection.extend({
    model: Subtab
});

// Tab Model
var Tab = Backbone.Model.extend({
    defaults: { label: undefined, subtabs: new Subtabs}
});

// Tabs Collection
var Tabs = Backbone.Collection.extend({
    model: Tab
});

Теперь, когда я изменяю атрибут tab, он запускает событие изменения в модели Tab, а также в коллекции Tabs (вполне нормально, правильно?), но когда я изменяю атрибут subtab, он запускает изменение событие в модели Subtab и Subtabs (это тоже нормально) , но оно не поддается модели Tab (и коллекции Tabs).

По крайней мере, я думаю, это должно быть потому, что коллекция внутри модели была изменена, и поэтому модель была изменена (но, возможно, я ошибаюсь, и я не получаю ее).

Любое предложение о том, как я могу добиться такого поведения с помощью Backbone?

Ответ 1

Событие A change запускается Backbone, когда атрибут изменяется через set. Событие затем также запускается в коллекции, как вы видели. Но значение вашего атрибута subtabs не изменяется вообще, это все тот же объект, который вы создали в defaults. Если вы использовали tab.set('subtabs', new Subtabs);, вы получили бы событие change:subtabs, но вы не хотите этого делать.

Я думаю, вам нужно будет что-то сделать в своем коде, чтобы вызвать новое событие в вашей модели вкладки.

// Tab Model
var Tab = Backbone.Model.extend({
    defaults: { label: undefined, subtabs: new Subtabs},
    initialize: function(){
        // listen for change in subtabs collection.
        this.get('subtabs').on('change', this.subtabsChanged, this);
    },
    subtabsChanged: function(model) {
        // trigger new event.
        this.trigger('subtab:change', this, model);
    }
});

Затем вы можете прослушать событие:

tabs.on('subtab:change', function(tab, subtab) { 
    console.log(tab.get('label'));
    console.log(subtab.get('label'));
});

Это будет работать, я думаю. Но я думаю, мне интересно, почему вы будете слушать коллекцию вкладок для изменения Subtabs. В большинстве случаев было бы лучше просто прослушать событие изменения в самой коллекции Subtabs.

tab.get('subtabs').on('change', function(model){
    // do something with model, which is a Subtab.
});

EDIT: http://jsfiddle.net/phoenecke/DvHqH/1/