Zniszcz lub usuń widok w Backbone.js

83

Obecnie próbuję zaimplementować metodę niszczenia / usuwania dla widoków, ale nie mogę uzyskać ogólnego rozwiązania działającego dla wszystkich moich widoków.

Miałem nadzieję, że będzie zdarzenie do dołączenia do kontrolera, tak aby nowe żądanie niszczyło poprzednie widoki, a następnie ładowało nowe.

Czy można to zrobić bez konieczności tworzenia funkcji usuwania dla każdego widoku?

Ad Taylor
źródło
Czy mógłbyś podać przykład swojego poglądu na ekosystem? Twoje pytanie sprawia, że ​​myślę, że strona ma wiele wyświetleń naraz. Nie jestem w stanie wyobrazić sobie tego, co próbujesz zrobić i dlatego nie mogę udzielić odpowiedzi, która może być tym, czego potrzebujesz.
Bill Eisenhauer
1
kilka innych wzorców z tych wspaniałych postów: lostechies.com/derickbailey/2011/09/15/… coenraets.org/blog/2012/01/...
daedelus_j

Odpowiedzi:

47

Nie znając wszystkich informacji ... Możesz powiązać wyzwalacz resetowania z modelem lub kontrolerem:

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

a kiedy chcesz zresetować widoki, wyzwalaj reset.

Aby oddzwonić, zrób coś takiego:

updateView: function() {
  view.remove();
  view.render();
};
joshvermaire
źródło
5
Myślę, że to nie jest w porządku. Funkcja usuwania widoku po prostu usuwa element tego widoku z DOM ( zobacz tutaj ). Myślę, że ten facet chce całkowicie usunąć obiekt widoku.
Nutritioustim
2
this.remove () kończy się wywołaniem metody remove () jquery, która również usuwa dane i zdarzenia ... Niemniej jednak myślę, że musisz również wywołać this.undelegateEvents, aby usunąć powiązanie z innymi zdarzeniami, takimi jak zdarzenia niestandardowe lub zmiany w modelu ..
otwiera się
21
this.remove()połączenia this.stopListening()i this.$el.remove(). Pierwsza usuwa wszystkie detektory zdarzeń dodane za pomocą this.listenTo(...). Druga usuwa wszystkie detektory zdarzeń dodane przy użyciu jQuery. Pomiędzy tymi dwoma, powinieneś zostać objęty, chyba że użyłeś innych sposobów dodawania detektorów zdarzeń. Więc ta odpowiedź jest poprawna i daje mi +1.
chowey
162

Musiałem być absolutnie pewien, że widok został nie tylko usunięty z DOM, ale także całkowicie niezwiązany z wydarzeniami.

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

}

Wydawało mi się to przesadą, ale inne podejścia do końca nie pomogły.

sdailey
źródło
10
z tego, co widziałem, this.remove () powinno wywołać usuwanie jQuery, które powinno usunąć element z DOM, ale także usunąć dane i zdarzenia z nim związane. Więc chyba wezwanie do undelegateEvents i removeData nie powinno być konieczne ... Czy mam rację?
otwiera się
1
@opensas Zdarzenia utrzymywały się poza this.remove () pomimo usunięcia elementu z DOM. Metoda this.undelegateEvents () była potrzebna do rozwiązania powiązania wszystkich zdarzeń. Jak powiedziałem, wydawało się, że to przesada, ale załatwiło sprawę.
sdailey
3
Lubię to. Chociaż powinieneś używać this.$elzamiast $(this.el);)
mreq
3
+1 za dobrą odpowiedź na mój problem, +1 za napisanie pierwszej odpowiedzi :)
1nfiniti
1
Mój widok nie jest renderowany ponownie po zniszczeniu i ponownym utworzeniu. Czy to z powodu this.remove()?
Raeesaa
20

Wiem, że spóźniłem się na przyjęcie, ale mam nadzieję, że przyda się to komuś innemu. Jeśli używasz wersji Backbone v0.9.9 +, możesz użyć listenToistopListening

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

stopListeningjest wywoływana automatycznie przez remove. Możesz przeczytać więcej tutaj i tutaj

Bassam Mehanni
źródło
8

To jest to, czego używałem. Nie widziałem żadnych problemów.

destroy: function(){
  this.remove();
  this.unbind();
}
JT703
źródło
4

Zgodnie z aktualną dokumentacją Backbone ....

view.remove ()

Usuwa widok i jego el z DOM i wywołuje stopListening, aby usunąć wszelkie powiązane zdarzenia, które widok ma ListenTo'd.

Dre
źródło
0

Myślę, że to powinno działać

destroyView : function () {
    this.$el.remove();
}
Chhorn Ponleu
źródło
Muszę też zabić słuchaczy, this.stopListening()a potem return thisna dokładkę
Brandon
0

Możesz użyć sposobu, aby rozwiązać problem!

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

Inny sposób : Utwórz zmienną globalną, taką jak ta:_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
źródło
Pierwsze podejście zadziałało dla mnie, napotkałem podobny problem z widmami widoków i zdarzeniami uruchamianymi wielokrotnie, gdy każdy widok był odtwarzany po przesłaniu formularza
ONYX,