Destruir o eliminar una vista en Backbone.js

83

Actualmente estoy tratando de implementar un método de destrucción / eliminación para las vistas, pero no puedo obtener una solución genérica que funcione para todas mis vistas.

Esperaba que hubiera un evento para adjuntar al controlador, de modo que cuando llegue una nueva solicitud, destruya las vistas anteriores y luego cargue las nuevas.

¿Hay alguna forma de hacer esto sin tener que crear una función de eliminación para cada vista?

Ad Taylor
fuente
¿Podría dar un ejemplo de cuál es su ecosistema de visión? Tu pregunta me hace pensar que hay muchas vistas en la página a la vez. No puedo visualizar lo que está tratando de hacer y, por lo tanto, no puedo ofrecer una respuesta que podría ser lo que necesita.
Bill Eisenhauer
1
algunos otros patrones de estas excelentes publicaciones: lostechies.com/derickbailey/2011/09/15/… coenraets.org/blog/2012/01/…
daedelus_j

Respuestas:

47

Sin conocer toda la información ... podría vincular un disparador de reinicio a su modelo o controlador:

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

y cuando desee restablecer las vistas, active un restablecimiento.

Para su devolución de llamada, haga algo como:

updateView: function() {
  view.remove();
  view.render();
};
Joshvermaire
fuente
5
No creo que esto sea correcto. La función de eliminación de la vista simplemente elimina el elemento de esa vista del DOM ( ver aquí ). Creo que este tipo quiere eliminar el objeto de vista por completo.
Nutritioustim
2
this.remove () termina llamando a remove () de jquery, que también elimina datos y eventos ... Sin embargo, creo que también debe llamar a this.undelegateEvents para desvincularse de otros eventos, como eventos personalizados o cambios en el modelo ..
opensas
21
this.remove()llamadas this.stopListening()y this.$el.remove(). El primero elimina todos los detectores de eventos agregados mediante this.listenTo(...). El segundo elimina todos los oyentes de eventos que se agregan usando jQuery. Entre los dos, debería estar cubierto a menos que haya utilizado algún otro medio para agregar detectores de eventos. Entonces esta respuesta es correcta y obtiene +1 de mí.
Chowey
162

Tenía que estar absolutamente seguro de que la vista no solo se eliminó del DOM sino que también se desvinculó por completo de los eventos.

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

}

Me pareció una exageración, pero otros enfoques no funcionaron por completo.

sdailey
fuente
10
Por lo que he visto, this.remove () debería llamar a la eliminación de jQuery, que debería eliminar el elemento del DOM pero también eliminar los datos y eventos adjuntos. Así que supongo que la llamada a undelegateEvents y removeData no debería ser necesaria ... ¿Estoy en lo cierto?
abre el
1
@opensas Los eventos persistían más allá de this.remove () a pesar de que el elemento se eliminó del DOM. this.undelegateEvents () era necesario para que todos los eventos se desvincularan. Como dije, se sintió como una exageración, pero funcionó.
sdailey
3
Me gusta. Aunque debería usar en this.$ellugar de $(this.el);)
mreq
3
+1 por una buena respuesta a mi problema, +1 por escribir su primera respuesta :)
1nfiniti
1
Mi punto de vista no se vuelve a renderizar al destruirlo y volverlo a crear. ¿Es por eso this.remove()?
Raeesaa
20

Sé que llego tarde a la fiesta, pero espero que esto sea útil para otra persona. Si está usando backbone v0.9.9 +, puede usar listenToystopListening

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

stopListeninges llamado automáticamente por remove. Puedes leer más aquí y aquí

Bassam Mehanni
fuente
8

Esto es lo que he estado usando. No he visto ningún problema.

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

Según la documentación actual de Backbone ...

view.remove ()

Elimina una vista y su el del DOM, y llama a stopListening para eliminar cualquier evento vinculado que la vista haya escuchado.

Dre
fuente
0

Creo que esto debería funcionar

destroyView : function () {
    this.$el.remove();
}
Chhorn Ponleu
fuente
Tener que matar a los oyentes también con this.stopListening()y luego return thispor si acaso
Brandon
0

¡Podrías usar la forma de resolver el problema!

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

Otra forma : Crea una variable global, como esta:_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
fuente
El primer enfoque funcionó para mí, me encontré con un problema similar con las vistas fantasma y los eventos se dispararon varias veces cuando cada vista se estaba recreando cuando envió el formulario
ONYX