Zerstören oder entfernen Sie eine Ansicht in Backbone.js

82

Ich versuche derzeit, eine Zerstörungs- / Entfernungsmethode für Ansichten zu implementieren, kann jedoch keine generische Lösung für alle meine Ansichten finden.

Ich hatte gehofft, dass es ein Ereignis geben würde, das an den Controller angehängt werden könnte. Wenn eine neue Anforderung eingeht, werden frühere Ansichten zerstört und die neuen geladen.

Gibt es eine Möglichkeit, dies zu tun, ohne für jede Ansicht eine Entfernungsfunktion erstellen zu müssen?

Ad Taylor
quelle
Können Sie ein Beispiel für Ihr Ökosystem geben? Ihre Frage lässt mich denken, dass es viele Aufrufe auf der Seite gleichzeitig gibt. Ich kann mir nicht genau vorstellen, was Sie versuchen, und kann daher keine Antwort anbieten, die genau das ist, was Sie brauchen.
Bill Eisenhauer
1
Einige andere Muster aus diesen großartigen Beiträgen: lostechies.com/derickbailey/2011/09/15/… coenraets.org/blog/2012/01/…
daedelus_j

Antworten:

47

Ohne alle Informationen zu kennen ... Sie könnten einen Reset-Trigger an Ihr Modell oder Ihren Controller binden:

this.bind("reset", this.updateView);

Wenn Sie die Ansichten zurücksetzen möchten, lösen Sie einen Reset aus.

Führen Sie für Ihren Rückruf Folgendes aus:

updateView: function() {
  view.remove();
  view.render();
};
Joshvermaire
quelle
5
Ich denke nicht, dass das richtig ist. Die Entfernungsfunktion der Ansicht entfernt nur das Element dieser Ansicht aus dem DOM ( siehe hier ). Ich denke, dieser Typ möchte das Ansichtsobjekt vollständig entfernen.
Nutritioustim
2
this.remove () ruft am Ende remove () von jquery auf, wodurch auch Daten und Ereignisse entfernt werden. Ich denke jedoch, dass Sie this.undelegateEvents auch aufrufen müssen, um sich von anderen Ereignissen wie benutzerdefinierten Ereignissen oder Änderungen am Modell zu lösen.
öffnet
21
this.remove()Anrufe this.stopListening()und this.$el.remove(). Der erste entfernt alle Ereignis-Listener, die mit hinzugefügt wurden this.listenTo(...). Die zweite Option entfernt alle Ereignis-Listener, die mit jQuery hinzugefügt wurden. Zwischen den beiden sollten Sie abgedeckt sein, es sei denn, Sie haben andere Methoden zum Hinzufügen von Ereignis-Listenern verwendet. Diese Antwort ist also richtig und bekommt +1 von mir.
Chowey
161

Ich musste absolut sicher sein, dass die Ansicht nicht nur aus DOM entfernt, sondern auch völlig ungebunden von Ereignissen war.

destroy_view: function() {

    // COMPLETELY UNBIND THE VIEW
    this.undelegateEvents();

    this.$el.removeData().unbind(); 

    // Remove view from DOM
    this.remove();  
    Backbone.View.prototype.remove.call(this);

}

Es schien mir übertrieben, aber andere Ansätze haben den Trick nicht vollständig geschafft.

Sdailey
quelle
10
Für das, was ich gesehen habe, sollte this.remove () jQuery's remove aufrufen, wodurch das Element aus dem DOM entfernt, aber auch damit verbundene Daten und Ereignisse entfernt werden sollen. Ich denke also, der Aufruf von undelegateEvents und removeData sollte nicht notwendig sein ... Habe ich recht?
öffnet
1
@opensas Ereignisse blieben nach this.remove () bestehen, obwohl das Element aus dem DOM entfernt wurde. this.undelegateEvents () wurde benötigt, damit sich alle Ereignisse lösen konnten. Wie gesagt, es fühlte sich wie ein Overkill an, aber es hat es geschafft.
Sdailey
3
Ich mag das. Obwohl Sie this.$elanstelle von verwenden sollten $(this.el);)
mreq
3
+1 für eine gute Antwort auf mein Problem, +1 für das Schreiben Ihrer ersten Antwort :)
1nfiniti
1
Meine Ansicht wird beim Rendern und erneuten Erstellen nicht neu dargestellt. Liegt es an this.remove()?
Raeesaa
20

Ich weiß, dass ich zu spät zur Party komme, aber hoffentlich ist dies für jemand anderen nützlich. Wenn Sie Backbone v0.9.9 + verwenden, können Sie listenTound verwendenstopListening

initialize: function () {
    this.listenTo(this.model, 'change', this.render);
    this.listenTo(this.model, 'destroy', this.remove);
}

stopListeningwird automatisch von aufgerufen remove. Hier und hier können Sie mehr lesen

Bassam Mehanni
quelle
8

Das habe ich benutzt. Ich habe keine Probleme gesehen.

destroy: function(){
  this.remove();
  this.unbind();
}
JT703
quelle
4

Laut aktueller Backbone-Dokumentation ....

view.remove ()

Entfernt eine Ansicht und ihr Element aus dem DOM und ruft stopListening auf, um alle gebundenen Ereignisse zu entfernen, für die die Ansicht listenTo'd hat.

Dre
quelle
0

Ich denke das sollte funktionieren

destroyView : function () {
    this.$el.remove();
}
Chhorn Ponleu
quelle
Müssen Zuhörer auch mit this.stopListening()und dann return thisfür ein gutes Maß töten
Brandon
0

Sie könnten den Weg nutzen, um das Problem zu lösen!

initialize:function(){
    this.trigger('remove-compnents-cart');
    var _this = this;
    Backbone.View.prototype.on('remove-compnents-cart',function(){
        //Backbone.View.prototype.remove;
        Backbone.View.prototype.off();
        _this.undelegateEvents();
    })
}

Ein anderer Weg: Erstellen Sie eine globale Variable wie folgt:_global.routerList

initialize:function(){
    this.routerName = 'home';
    _global.routerList.push(this);
}
/*remove it in memory*/
for (var i=0;i<_global.routerList.length;i++){
    Backbone.View.prototype.remove.call(_global.routerList[i]);
}
Deot
quelle
Der erste Ansatz hat bei mir funktioniert. Ich hatte ein ähnliches Problem mit Ansichten-Ghosting und die Ereignisse wurden mehrmals
ausgelöst,