javascript meteor handlebars.js

javascript - El contexto de "esto" en los manejadores de eventos de plantillas de Meteor(usando Manubrios para plantillas)



handlebars.js (2)

El primer parámetro en la función es el evento. Entonces puedes usar el objetivo del evento para tomar tu elemento.

Template.scores.events({ ''click .click-me'': function (event, template) { console.log(event.target); $(event.target).text("O but I did!"); } });

Una pregunta rápida sobre el contexto de los manejadores de eventos para plantillas en Meteor (con manubrios).

  • En la sección de Documentación sobre instancias de plantilla ( http://docs.meteor.com/#template_inst ) se menciona que "los objetos de instancia de plantilla se encuentran como el valor de esto en las devoluciones de llamada de plantilla creadas, renderizadas y destruidas y como una argumento para los controladores de eventos "
  • En la sección Plantillas ( http://docs.meteor.com/#templates ) dice " Finalmente, puede usar una declaración de eventos en una función de plantilla para configurar una tabla de controladores de eventos. El formato está documentado en Event Maps. El argumento para el controlador de eventos será el contexto de datos del elemento que desencadenó el evento " .

Bueno, esto es parcialmente cierto. Usemos un ejemplo de los documentos:

<template name="scores"> {{#each player}} {{> playerScore}} {{/each}} </template> <template name="playerScore"> <div>{{name}}: {{score}} <span class="givePoints">Give points</span> </div> </template Template.playerScore.events({ ''click .givePoints'': function () { Users.update({_id: this._id}, {$inc: {score: 2}}); });

Aquí el contexto "this" del controlador de eventos "click .givePoints" es de hecho la instancia de plantilla de playerScore. Modifiquemos el html:

<template name="scores"> <span class="click-me">Y U NO click me?<span> {{#each player}} {{> playerScore}} {{/each}} </template> <template name="playerScore"> <div>{{name}}: {{score}} <span class="givePoints">Give points</span> </div> </template>

... y agrega un controlador de eventos para .click-me en la plantilla de puntajes:

Template.scores.events({ ''click .click-me'': function () { console.log(this); } });

Ahora, si haces clic en el lapso, ¿qué obtienes? ¡El objeto ventana! ¿Qué esperaba obtener? ¡El objeto plantilla! O tal vez el contexto de datos, pero no es ninguno. Sin embargo, dentro de las devoluciones de llamadas (por ejemplo, Template.scores.rendered = function () {...}) el contexto de "this" es siempre la instancia de la plantilla.

Creo que mi verdadera pregunta sería: ¿esto tiene que ver con

  • un error en los manubrios, Meteor o en algún punto intermedio?
  • documentación un poco incompleta en las plantillas?
  • ¿Estoy malinterpretando completamente los documentos o no entendiendo algo fundamental sobre Meteor o Handlebars?

¡Gracias!


Este video explica los conceptos:

http://www.eventedmind.com/posts/meteor-spark-data-annotation-and-data-contexts .

La respuesta directa a tu pregunta:

El thisArg dentro de un manejador de eventos debe apuntar a un contexto de datos. Pero a veces el contexto de datos undefined está undefined . Cuando utiliza Function.prototype.call(thisArg, ...) en JavaScript, si thisArg no está definido (por ejemplo, un dataContext no está definido) el navegador configurará this ventana. Por lo tanto, los documentos no son incorrectos per se, pero el código de manejo de eventos no protege contra la posibilidad de que un contexto de datos no esté definido. Supongo que será arreglado en poco tiempo.

Entonces, ¿qué produce un contexto de datos para una plantilla? Normalmente, su plantilla raíz ni siquiera tendrá un contexto de datos. En otras palabras, la función de Plantilla se llama sin un objeto. Pero si usa el {{#with block helper o el {{#each , se {{#each un contexto de datos para cada elemento de la lista, o en el caso de el helper, el objeto.

Ejemplo:

var context = {}; <template name="withHelper"> {{#with context}} // data context is the context object {{/with}} </template> var list = [ {name: "one"}, {name: "two"} ]; <template name="list"> {{#each list}} {{ > listItem }} // data context set to the list item object {{/each}} </template>