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?


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

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.


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


8

Das habe ich benutzt. Ich habe keine Probleme gesehen.

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

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.


0

Ich denke das sollte funktionieren

destroyView : function () {
    this.$el.remove();
}

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

Der erste Ansatz hat bei mir funktioniert. Ich hatte ein ähnliches Problem mit Ansichten-Ghosting und die Ereignisse wurden mehrmals
ausgelöst,
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.