“这个”的上下文在Meteor模板事件处理程序中(使用Handlebars进行模板化) [英] The context of "this" in Meteor template event handlers (using Handlebars for templating)

查看:69
本文介绍了“这个”的上下文在Meteor模板事件处理程序中(使用Handlebars进行模板化)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有关流星中模板的事件处理程序(使用Handlebars)的上下文的快速问题。




  • 在模板实例的文档部分( http://docs.meteor.com/#template_inst )提到模板实例对象在创建,渲染和销毁的模板回调中被找到,而一个事件处理程序的参数

  • 在模板部分( http ://docs.meteor.com/#templates )它说最后,你可以在模板函数上使用事件声明来设置一个事件处理程序的表格。 。该事件处理程序的这个参数将是触发该事件的元素的数据上下文



    • 好吧,这只是部分正确的。我们使用文档中的示例:

       < template name =scores> 
      {{#each player}}
      {{> playerScore}}
      {{/ each}}
      < / template>

      < template name =playerScore>
      < div> {{name}}:{{score}}
      < span class =givePoints>给点< / span>
      < / div>
      Template.playerScore.events({
      'click .givePoints':function(){
      Users.update({_ id:this._id},{ $ inc:{score:2}});
      });

      这里的'click .givePoints'事件处理程序的this上下文确实是模板实例playerScore。让我们修改html:

       < template name =scores> 
      < span class =click-me>是否否点击我?< span>
      {{#each player}}
      {{> playerScore}}
      {{/ each}}
      < / template>

      < template name =playerScore>
      < div> {{name}}:{{score}}
      < span class =givePoints>给点< / span>
      < / div>
      < / template>

      ...并为分数模板上的.click-me添加事件处理程序:

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

      现在,如果您单击跨度,您会记录什么? Window对象!我期望得到什么?模板对象!或者可能是数据上下文,但它不是。但是,在回调中(例如Template.scores.rendered = function(){...}),this的上下文始终是模板实例。



      我想我的真正问题是:这是与什么有关




      • Handlebars,Meteor或其他地方的错误?

      • 模板上的文档稍微不完整

      • 我完全误解了文档,或者没有理解基本的
        关于Meteor或Handlebars的内容? li>


      感谢! 解释了这些概念:

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

      直接回答您的问题:

      事件处理程序内的thisArg应指向数据上下文。但有时数据上下文是 undefined 。当您在JavaScript中使用 Function.prototype.call(thisArg,...)时,如果thisArg未定义(例如dataContext未定义),浏览器将设置这个等于窗口。因此,文档本身并不是错误的,但事件处理代码并未防范数据上下文未定义的可能性。我猜这将在短期内得到修复。



      那么,为模板产生数据上下文的是什么呢?通常你的根模板甚至没有数据上下文。换句话说,模板函数在没有对象的情况下被调用。但是,如果您使用 {{#with block助手或 {{#each 迭代器,数据上下文将会为列表中的每个项目创建,或者在使用助手的情况下创建对象。



      示例:

        var context = {}; 

      < template name =withHelper>
      {{#with context}}
      //数据上下文是上下文对象
      {{/ with}}
      < / template>

      var list = [{name:one},{name:two}];

      < template name =list>
      {{#each list}}
      {{> listItem}} //将数据上下文设置为列表项对象
      {{/ each}}


      A quick question on the context of the event handlers for templates in Meteor (with Handlebars).

      • In the section of Documentation on template instances (http://docs.meteor.com/#template_inst) it is mentioned that "Template instance objects are found as the value of this in the created, rendered, and destroyed template callbacks and as an argument to event handlers"
      • In the Templates section (http://docs.meteor.com/#templates) it says "Finally, you can use an events declaration on a template function to set up a table of event handlers. The format is documented at Event Maps. The this argument to the event handler will be the data context of the element that triggered the event."

      Well, this is only partially true. Let's use an example from the docs:

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

      Here the "this" context of the 'click .givePoints' event handler is indeed the template instance of playerScore. Let's modify the 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>
      

      ... and add an event handler for .click-me on the scores template:

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

      Now, if you click the span, what do you get logged? The Window object! What did I expect to get? The template object! Or maybe the data context, but it's neither. However, inside the callbacks (e.g. Template.scores.rendered = function(){ ... }) the context of "this" is always the template instance.

      I guess my real question would be: is this something to do with

      • a bug in Handlebars, Meteor or somewhere in between?
      • slightly incomplete documentation on the templates?
      • me completely misinterpreting the docs or not understanding something fundamental about Meteor or Handlebars?

      Thanks!

      解决方案

      This video explains the concepts:

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

      The direct answer to your question:

      The thisArg inside an event handler should point to a data context. But sometimes the data context is undefined. When you use the Function.prototype.call(thisArg, ...) in JavaScript, if the thisArg is undefined (e.g. a dataContext is undefined) the browser will set this equal to window. So, the docs aren't wrong per se but the event handling code isn't guarding against the possibility of a data context being undefined. I'm guessing that will be fixed in short order.

      So, what produces a data context for a template? Normally your root template won't even have a data context. In other words, the Template function is called without an object. But if you use the {{#with block helper or the {{#each iterator, a data context will be created for each item in the list, or in the case of the with helper, the object.

      Example:

      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>
      

      这篇关于“这个”的上下文在Meteor模板事件处理程序中(使用Handlebars进行模板化)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆