2011-03-11 17 views
17

Estoy usando Backbone.js tengo un elemento de interfaz de usuario de tipo control segmentado para cada vista de modelo. Cada uno está formado por un ul con algunos elementos li. Quiero vincular un evento de modo que cuando se haga clic en uno de estos elementos, pueda determinar en cuál se ha hecho clic y actualizar el modelo con el valor apropiado.Backbone.js Enlazado de evento

El problema es que el Backbone vincula los eventos (estos se encuentran en el hash de eventos de la vista) de manera que "this" en la función de devolución de llamada se refiere a la vista, no a los elementos li. Esto significa que no puedo determinar en cuál de los varios elementos Li ha hecho clic. Si utilicé un enlace jQuery normal, puedo vincular "esto" a los elementos li, pero ya no tengo un seguimiento del modelo, así que no puedo actualizarlo.

Respuesta

44

hábito de jQuery de establecer this a lo que pasa a ser conveniente en el momento es un patrón bastante desagradable, en mi opinión - afortunadamente, nunca se tiene que confiar en él:

onClick: function(e) { 
    this;    // Still the view instance (as it should be). 
    e.target;   // The element that was clicked. 
    e.currentTarget;  // The element that was bound by the click event. 
} 

... Usted puede usar target o currentTarget del objeto de evento, según corresponda.

+0

Eso, e, Internet Explorer tiene la mala costumbre de interpretar 'this' como' ventana' si su alcance no está limpio. – rxgx

+0

Esto solo funciona para eventos desencadenados por jquery, ¿verdad? Los eventos activados a través de la función trigger() de la red troncal no transmitirán un evento jquery, sino que los argumentos que haya ingresado en trigger() –

+2

@JensAlm. Correcto. La función .trigger() de Backbone desencadena eventos en modelos de Backbone, mientras que la lista de 'eventos' de Backbone está conectada a delegateEvents de jQuery. Son dos sistemas de eventos diferentes. –

20

No puedo entender por qué no puedo comentar la respuesta de @jashkenas anterior. Su método es correcto (¡gracias!), Pero pensé en aclarar la situación: en el controlador de eventos, puede recuperar el elemento al que estaba destinado el evento. código de la columna vertebral de la muestra se vería así:

MyView = Backbone.View.extend({ 
    events: { 
     'click .item': 'handleClick' 
    }, 

    handleClick: function(e) { 
     this; // The view instance 
     e.target; // The element that was clicked 
     e.currentTarget; // The element that was bound by the click event 
    } 
}); 

Lo utilizo para la configuración por defecto de texto en todos mis campos de formulario ... sí yo no soy mucho en HTML5 todavía :)

Editar: Por cierto, e.target es el elemento crudo. Deberá usar $ (e.target) para obtener acceso a jQuery.

+0

Este es el camino a seguir si está utilizando la red troncal. – UpTheCreek

+0

Todavía parece tonto que usted tenga que saber que tiene que saber la clase CSS de lo que se está haciendo clic. Algo como '' haga clic aquí. $ El ':' handleClick '' sería preferible. – bergie3000

+1

No es cojo, ya que puede tener diferentes comportamientos asignados a los elementos contenidos en la vista de su objeto (por ejemplo, un enlace para editar, otro para eliminar, colocado junto al título de su elemento, este título lo lleva a la vista del programa cuando hace clic) ¿O estoy equivocado al pensar eso? – Ben

Cuestiones relacionadas