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?


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

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.


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


8

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

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

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.


0

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

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

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

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,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.