2016-05-07 8 views
0

Ich habe eine Ansicht (ich werde Eltern nennen), die eine andere Ansicht innerhalb davon (eine untergeordnete Ansicht) hat. Die übergeordnete Ansicht enthält Elemente, die ein "Kontextmenü" -Ereignis verwenden (beim Klicken mit der rechten Maustaste wird eine Reihe von Menüoptionen angezeigt). Wenn ein Benutzer ein Element aus dem Menü auswählt, wird ein Rückruf ausgelöst. Von dort trigger ich ein Ereignis in der Kindansicht. Hier mein Trigger ist:Backbone.js ListenToOnce wird zweimal aufgerufen

that.trigger("editFileFolder", {fileType: fileType}); 

In meinem Kind nach Ansicht der Initialisierungsfunktion, ich habe dies:

this.listenToOnce(this.options.parent,'editFileFolder', this.editFileObjectEvent); 

Die editFileObjectEvent Funktion ruft eine andere Ansicht erstellt werden (einen Dialog mit einigen Feldern, eine Löschtaste und eine Schaltfläche zum Speichern). Wenn der Benutzer auf Abbrechen klickt, funktioniert alles einwandfrei. Wenn der Benutzer auf die Schaltfläche Speichern klickt, führt die Ansicht einen Ajax-Aufruf aus, speichert sie auf dem Server und schließt das Dialogfeld. Aber wenn das nächste Mal der Benutzer mit der rechten Maustaste klickt und denselben Menüeintrag auswählt, wird das editFileObjectEvent zweimal aufgerufen (was dazu führt, dass der Dialog zweimal zur übergeordneten Ansicht hinzugefügt wird).

Kann jemand erklären, warum es zweimal angerufen wird und wie man das löst? Wenn Sie spezifischen Code sehen möchten, lassen Sie es mich wissen und ich kann es hinzufügen. Es gibt eine Menge, also möchte ich die Frage nicht überfordern.

dank

+0

Ich denke, die Funktion, die 'this.listenToOnce' nennen zweimal aufgerufen wird – andlrc

+0

hmm, scheint, dass Sie richtig sind. Gibt es eine Möglichkeit festzustellen, ob dieser Listener bereits vorhanden ist, sodass ich es vermeiden kann, ihn erneut hinzuzufügen? – jason

+0

Ich denke nicht, obwohl die öffentliche API. Aber du könntest 'this._listeningTo' betrachten – andlrc

Antwort

2

Ich denke, die Funktion, die this.listenToOnce ruft zweimal aufgerufen wird. Sie sollten versuchen, dies zu vermeiden. Allerdings, wenn dies nicht möglich ist, können Sie die Hörer sicher nur, wenn es gebunden ist, durch freibleibend vor der Bindung:

this.stopListening(this.options.parent, 'editFileFolder', this.editFileObjectEvent); 
this.listenToOnce(this.options.parent, 'editFileFolder', this.editFileObjectEvent); 

Oder Sie könnten eine Eigenschaft auf die Instanz von der Bindung zweimal zu verhindern haben:

if (!this.__boundListener) { 
    this.listenToOnce(this.options.parent, 'editFileFolder', this.editFileObjectEvent); 
    this._boundListener = true; 
} 

Alle Listener sind in this._listeningTo registriert und Sie können möglicherweise suchen, um zu überprüfen, ob das Ereignis bereits gebunden ist.

Sie können auch Ihren Code Refactoring:

MyModel.extend({ 
    initialize: function() { 
    this.bindListenToOnce = _.once(this.bindListenToOnce); 
    }, 
    abc: function() { 
    // do stuff 
    this.bindListenToOnce(); 
    // do stuff 
    }, 
    bindListenToOnce: function() { 
    this.listenToOnce(this.options.parent, 'editFileFolder', this.editFileObjectEvent); 
    } 
}); 
Verwandte Themen