2013-04-06 4 views
11

Ich habe eine Backbone-App, die verschachtelte Sammlungen verwendet (zumindest so denke ich, dass sie genannt werden).Wie kann ich Ereignisse in verschachtelten Backbone-Sammlungen "aufblasen"?

In meinem speziellen Fall gibt es tabs und Subreiter, und jede Lasche (Modell) enthält eine Sammlung von Unterregistern (Modell).

Für diejenigen, die mit dem Code vertraut sind, werde ich schreibe meine Modelle und Sammlungen unten, und wie untergeordneten Registerkarten innerhalb der Registerkarte Modell verschachtelt:

// 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 
}); 

Nun, wenn ich es eine Registerkarte Attribut ändern feuert das Änderungsereignis auf dem Tab Modell und auch auf der Tabs Sammlung (ganz normal, oder?), aber wenn ich ein Unterregister Attribut ändern, löst es das Änderungsereignis auf Subtab Modell und Subtabs Sammlung (das ist auch normal) aber es sprudelt nicht bis zum Tab Modell (und zur Tabs Sammlung).

Zumindest, ich denke es sollte, weil eine Sammlung in einem Modell geändert wurde und so das Modell geändert wurde (aber vielleicht liege ich falsch und ich bekomme es nicht).

Jeder Vorschlag, wie kann ich dieses Verhalten mit Backbone erreichen?

+0

Trigger das Ereignis manuell, wenn Sie es erhalten –

+0

@CoryDanielson ich, dass das Ereignis gedacht benötigt ‚manuell‘ ausgelöst werden, aber es hat nicht funktioniert, ich habe _RangeError: Maximale Call-Stack Größe überschritten_. –

+0

Machst du etwas mit setTimeout? Das ist kein Fehler, den ich jemals zuvor bei der Verwendung von Backbone bekommen habe –

Antwort

7

Ein Ereignis wird von Backbone ausgelöst, wenn sich ein Attribut über set ändert. Das Ereignis wird dann auch bei der Sammlung ausgelöst, wie Sie gesehen haben. Aber der Wert Ihres subtabs Attributs ändert sich überhaupt nicht, es ist immer noch das gleiche Objekt, das Sie in defaults erstellt haben. Wenn Sie tab.set('subtabs', new Subtabs); verwenden, erhalten Sie ein change:subtabs Ereignis, aber Sie möchten das nicht tun.

Ich denke, Sie müssten etwas in Ihrem Code tun, um ein neues Ereignis auf Ihrem Tab-Modell auszulösen.

// 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); 
    } 
}); 

Dann sind Sie für die Veranstaltung hören konnte:

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

Dies funktioniert, denke ich. Aber ich denke, ich frage mich, warum Sie Ihre Tabs-Sammlung für eine Änderung in den Untertabellen hören würden. In den meisten Fällen ist es möglicherweise besser, nur auf das Änderungsereignis in Ihrer Subtabs-Sammlung selbst zu warten.

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

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

+0

Basierend auf Ihrer Antwort und mit einigen Änderungen an Ihrem Code, konnte ich das ursprüngliche "change" -Ereignis auf dem Modell auslösen. Ich habe es falsch gemacht, das 'change'-Ereignis ohne Kontext zu binden' this.get ('subtabs'). On ('change', thisbtabsChanged, this); 'und ich bekam einen Fehler _RangeError: Maximale Call-Stack-Größe überschritten_ . Also, das ist der Schlüssel. –

+0

Was macht thisbtabsChanged? –

+0

@CoryDanielson Ein Ereignis auf der Registerkarte auslösen, wenn etwas in der untergeordneten Sammlung geändert wird ... –

Verwandte Themen