Backbone.js: gewusst wie: Bindung von Veranstaltungen, auf Modell entfernen
im backbone haben wir eine app, die mithilfe eines event-Aggregator, der sich auf der window.App.Events
nun, in vielen Ansichten, wir binden zu, dass aggregator, und ich manuell schrieb zerstören-Funktion, eine Ansicht, die Griffe unverbindlich aus, dass der event aggregator und dann das entfernen der anzeigen. (anstatt direkt das entfernen der anzeigen).
nun, es gab bestimmte Modelle, bei denen mussten wir diese Funktionalität als gut, aber ich kann nicht herausfinden, wie man es angehen.
bestimmte Modelle zu binden, müssen bestimmte Ereignisse, aber vielleicht bin ich Irre, aber wenn wir so löschen Sie ein Modell aus einer Sammlung, es bleibt in Erinnerung wegen dieser Bindung an das Ereignis-aggregator, die sind noch im Ort.
gibt es nicht wirklich eine entfernen-Funktion auf einem Modell, wie ein view hat.
also, wie würde ich tacke das?
BEARBEITEN
auf Wunsch einiger code-Beispiel.
App = {
Events: _.extend({}, Backbone.Events)
};
var User = Backbone.Model.extend({
initialize: function(){
_.bindAll(this, 'hide');
App.Events.bind('burglar-enters-the-building', this.hide);
},
hide: function(burglarName){
this.set({'isHidden': true});
console.warn("%s is hiding... because %s entered the house", this.get('name'), burglarName);
}
});
var Users = Backbone.Collection.extend({
model: User
});
var House = Backbone.Model.extend({
initialize: function(){
this.set({'inhabitants': new Users()});
},
evacuate: function(){
this.get('inhabitants').reset();
}
});
$(function(){
var myHouse = new House({});
myHouse.get('inhabitants').reset([{id: 1, name: 'John'}, {id: 1, name: 'Jane'}]);
console.log('currently living in the house: ', myHouse.get('inhabitants').toJSON());
App.Events.trigger('burglar-enters-the-building', 'burglar1');
myHouse.evacuate();
console.log('currently living in the house: ', myHouse.get('inhabitants').toJSON());
App.Events.trigger('burglar-enters-the-building', 'burglar2');
});
Ansicht dieser code in Aktion auf jsFiddle (Ausgabe in der Konsole): http://jsfiddle.net/saelfaer/szvFY/1/
wie Sie sehen können, ich nicht binden die Ereignisse auf dem Modell, aber zu einem event aggregator.
unverbindliche Ereignisse aus dem Modell selbst, ist nicht notwendig, denn wenn es entfernt wird, niemand wird jemals ein Ereignis auslösen, auf es wieder. aber die eventAggregator-ist immer an Ort und Stelle, für die einfache Weitergabe der Ereignisse durch die gesamte app.
code-Beispiel zeigt, dass selbst dann, wenn Sie aus der Auflistung entfernt, Sie Leben nicht in dem Haus nicht mehr, aber noch führen Sie den Befehl "ausblenden" wenn ein Einbrecher das Haus betritt.
- Für ein besseres Verständnis deiner Frage wäre schön zu sehen, ein paar Zeilen code mit Beispielen, wie und wo Sie
bind
die Modell-Ereignisse, die Sie wollenunbind
wenn das Modell entfernt wird. Sehen Sie die Anweisungen des event-Bindung ist sehr wichtig. - das problem heißt Ghost Ansichten. Während
model.destroy()
Sicht sollte in der Lage sein zu bindendestroy
Veranstaltung. Während die die jeweiligen Ereignisse müssen nicht Delegierten und dann der Blick muss zerstört werden. - die Geist-Ansichten sind kein problem, diese werden ordnungsgemäß gelöscht, siehe meine exanple, es ist noch nicht einmal mit Ansichten arbeiten an diesem Zustand, nur Modelle und Kollektionen, die Bindung an einen aggregator. wenn Modelle entfernt werden, es gibt Sie noch (gebunden und ausgeführt werden, wenn das Ereignis aufgerufen wird)
- Ich sehe das binding-Ereignis-Richtung ist Modell -> Aggregator, also gibt es keine Referenz vom Aggregator-Modell, so dass Sie nicht haben, etwas zu clean-up nach dem Modell entfernt wird.
- Sich das Modell noch gebunden ist, wie Sie sehen können, in der er beispielsweise, obwohl er 2 Personen, die entfernt von den Benutzer-Sammlung im Haus, Sie weiterhin führen die Funktion zum ausblenden, wenn das Ereignis ausgelöst wird. also klar, Sie sind nicht richtig remvoed... und das ist es, was ich versuche zu erreichen, befreit Sie von er-aggregator, so dass Sie freien Speicher, den Sie benutzen 🙂
- Ja, du hast Recht, ich habe keine Lösung gefunden, aber ich habe ein jsFiddle mit weniger code, noch reproduziert das Problem
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich sehe, dass selbst, wenn die Bindung Ereignis-Richtung ist auf diese Weise Objekt1 -> Hör -> Objekt2 es muss entfernt werden, um Objekt1 verloren, lebendig Referenz.
Und zu sehen, dass hören auf das Modell
remove
Ereignis ist keine Lösung, weil es nicht als einCollection.reset()
nennen, dann haben wir zwei Lösungen:1. Überschreiben der normalen Auflistung Bereinigung
Als @dira ORKB hier können Sie überschreiben
Collection._removeReference
zu machen eine ordnungsgemäße Reinigung der Methode.Ich weiß nicht, wie diese Lösungen aus zwei Gründen:
super
nach.2. Über-Verpackung Ihr
Collection.reset()
AnrufeWich ist genau das Gegenteil: anstatt tiefer Funktionalität, fügen Sie oberen Funktionalität.
Dann anstelle von aufrufen
Collection.reset()
direkt aufrufen Sie können eine Implementierung, die Bereinigung die Modelle vor wurde stillschweigend entfernt:Einer sorter-version kann der code sieht wie folgt aus:
Überprüfen der jsFiddle.
Update: Nachweis, dass das Modell entfernt wird, nach entfernen der Bindung-event link
Erste, was wir überprüfen, dass Objekt1 hören, ein Ereignis in Objekt2 erzeugt einen link in die Richtung Obect2 -> Objekt1:
In der Abbildung oben sehen wir, wie das Modell (@314019) nicht nur beibehalten, indem der
users
Sammlung, sondern auch für dieAppEvents
Objekt, das zu beobachten. Sieht aus wie die Ereignis verknüpfen für einen Programmierer Perspektive ist Objekt, das zu hören -> zu> Objekt, das hörte aber in der Tat ist das genaue Gegenteil: Objekt gehört -> zu> Objekt, das hört.Nun, wenn wir die
Collection.reset()
zum entleeren der Sammlung sehen wir alsusers
link wurde entfernt, aber dieAppEvents
link bleibt:Den
users
link hat verschwinden und auch den linkOurModel.collection
was ich denke, ist Teil derCollection._removeReference()
job.Wenn wir unsere
Collection.cleanUp()
Methode das Objekt verschwindet aus dem Gedächtnis, kann ich nicht machen, dieChrome.profile
tool explizit sagt mir das Objekt @314019 entfernt wurde aber ich kann sehen, dass es nicht mehr unter dem memory-Objekte.v0.9.2
im letzten jsFiddle war es einv5 something
version von Rückgrat.Ich denke, dass die saubere Referenzen Prozess ist eine schwierige Teil der
Backbone
.Beim entfernen einer
Model
aus einerCollection
die Sammlung kümmert sich umunbind
jedem Fall auf das Modell, das der Kollektion Ihren selbst verbindlich ist. Check this private Collection-Methode.Vielleicht können Sie verwenden dieselbe Technik in Ihrem Aggregator:
Dies ist in dem Fall die Richtung der Bindung ist Aggregator -> Modell. Wenn die Richtung ist das Gegenteil ich glaube nicht, dass Sie haben, um die Reinigung nach dem Modell entfernt.
Collection.reset()
situation.Anstelle von Geschenkpapier
Collection
'sreset
mitcleanUp
als fguillen vorgeschlagen, ich bevorzuge die ErweiterungCollection
und überschreibenreset
direkt. Der Grund dafür ist, dasscleanUp
wirksam nur in client-code, aber nicht in der Bibliothek(d.h. Rückgrat)'s.Zum Beispiel
Collection.fetch
können intern anrufenCollection.reset
. Es sei denn, ändern der Rückgrat ist source-code, wir können nicht zuordnen Modelle von Ereignissen(wie incleanUp
) nach dem Aufruf vonCollection.fetch
.Grundsätzlich meine vorgeschlagenen snippet ist wie folgt:
Später, können wir neue Sammlungen erstellen, basierend auf
MyCollection
.