2012-06-11 25 views
11

¿Por qué debo crear un close prototype completo solo para tener mis eventos desagregados de mi vista? ¿No debería Backbone simplemente construir eso? ¿Hay alguna forma de detectar cuándo se está eliminando una vista?Eventos de red troncal que se activan dos veces

Mis eventos principales se disparan dos veces después de que me alejo y regreso a la vista.

 events : { 
      "click #userDropdownButton > a" : "toggleUserDropdownMenu", 
      "click" : "hideUserDropdownMenuIfClickedOutside" 
     }, 

     el : "body", 

     initialize : function() { 
      this.render(); 
     }, 

     // Shows/hides the user dropdown menu 
     toggleUserDropdownMenu : function() { 
      if(!this.$el.find('#userDropdownButton > ul').is(':visible')) { 
       this.showUserDropdownMenu(); 
      } else { 
       this.hideUserDropdownMenu(); 
      } 
      return false; 
     }, 
     showUserDropdownMenu : function() { 
      this.$el.find('#userDropdownButton').addClass('hover'); 
      this.$el.find('#userDropdownButton > ul').show(); 
      this.$el.find('#userDropdownButton > a .arrow-down').removeClass('arrow-down').addClass('arrow-up'); 
     }, 
     hideUserDropdownMenuIfClickedOutside : function() { 
      if(this.$el.find('#userDropdownButton > ul').is(':visible')) { 
       this.hideUserDropdownMenu(); 
      } 
     }, 
     hideUserDropdownMenu : function() { 
      this.$el.find('#userDropdownButton').removeClass('hover'); 
      this.$el.find('#userDropdownButton > ul').hide(); 
      this.$el.find('#userDropdownButton > a .arrow-up').removeClass('arrow-up').addClass('arrow-down'); 
     }, 

La primera vez que la vista se representa, el menú desplegable se abre y cierra correctamente, pero en el segundo tiempo de la vista se representa, en el menú desplegable interpreta cada clic dos veces, así que tan pronto como se abra, la segunda posición se cierra eso.

+1

Si supiéramos lo que estaba haciendo, probablemente podríamos decirle lo que está haciendo mal. Tal vez si hubiera algún código para mirar ... –

+0

@muistoo código agregado corto :) gracias por los comentarios – Garrett

+0

Llamaré a esto un duplicado de http://stackoverflow.com/q/10966440/479863 o al menos la respuesta es más o menos la misma. –

Respuesta

14

actualización 05/01/2013: 0.9.9+ Backbone ha añadido alguna funcionalidad integrada para facilitar la fácil tratar con teh problema zomg (ver View.remove y StopListening); pero aún necesitarás matar a tus zombies llamando a uno de estos.


¿Por qué debo crear un prototipo estrecha entero sólo para tener mis eventos unbinded desde mi punto de vista?

Derick's article es increíble en la cobertura de este problema. Pero puedo agregar mis dos bits, abordando su pregunta de "por qué" no está incorporada.

Debido a la forma en que funciona la delegación de eventos Backbone, las vistas no se recolectarán cuando salgan del alcance si tienen enlaces de eventos. Esto se debe a que los objetos cuyos eventos vinculan: objetos de red troncal, en el caso de vincularse a eventos de objetos de red troncal, o el sistema de eventos de DOM en el caso de devoluciones de llamada de "eventos", mantienen referencias a las funciones de la vista.

Lo crean o no, algunos usuarios de Backbone confían en este comportamiento y esperan que las vistas continúen respondiendo automáticamente a eventos como se les dijo que hicieran, incluso si se salieron completamente del alcance. (He visto varios tutoriales que hacen esto.) Esto supone que nunca es necesario eliminar la vista, o que la vista puede responder a eventos y eliminarse, ya que ha perdido cualquier referencia a ella, pero IMO, esto ' crear y olvidar 'la funcionalidad es agradable siempre que comprenda las implicaciones.

mu is too short hace un buen punto acerca de los eventos de IU. Eliminar el el del DOM también debería eliminar los eventos delegados. No se puede decir lo mismo de vincular eventos de modelo o colección u otros eventos de objetos de Backbone (cualquier objeto puede ampliar el prototipo de Backbone Events). Deberá seguir los consejos de Derick Bailey en el artículo al que se vincula y cerrar manualmente la vista en estos casos. No estoy seguro si esto es una debilidad de Backbone en comparación con otros frameworks JS MVC, no he probado otros en profundidad.

"¿Hay alguna forma de detectar cuándo se está eliminando una vista?"

No directamente, que yo sepa. Pero, en general, el código que elimine la vista también debe limpiar los enlaces de eventos si es necesario. A menudo, en buenas arquitecturas MVC, las vistas pueden configurar un observador de eventos en un modelo o colección correspondiente, y luego eliminar la limpieza & en función del evento que ocurra (por ejemplo, el evento "eliminar" del modelo correspondiente). Si desea que la eliminación de sus vistas sea universalmente "detectable", una forma sería anular la función de eliminación en su propio prototipo de vista y desencadenar un evento personalizado que otros puedan observar.

Cuestiones relacionadas