“this"的上下文在 Meteor 模板事件处理程序中(使用 Handlebars 进行模板化)

编程入门 行业动态 更新时间:2024-10-18 01:39:47
本文介绍了“this"的上下文在 Meteor 模板事件处理程序中(使用 Handlebars 进行模板化)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

关于 Meteor(带 Handlebars)中模板的事件处理程序上下文的快速问题.

  • 在关于模板实例的文档部分 (docs.meteor/#template_inst) 是提到模板实例对象在创建、呈现和销毁的模板回调中作为 this 的值被发现,并且作为事件处理程序的参数"
  • 在模板部分 (docs.meteor/#templates) 上写着最后,您可以在模板函数上使用事件声明来设置事件处理程序表.事件映射中记录了格式.事件处理程序的this 参数将是数据触发事件的元素的上下文."

嗯,这只是部分正确.让我们使用文档中的示例:

{{#每个玩家}}{{>球员得分}}{{/每个}}<模板名称="playerScore"><div>{{name}}:{{score}}<span class="givePoints">给分</span>

</模板Template.playerScore.events({'点击.给点':函数(){Users.update({_id: this._id}, {$inc: {score: 2}});});

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

<span class="click-me">你不点击我吗?<span>{{#每个玩家}}{{>球员得分}}{{/每个}}<模板名称="playerScore"><div>{{name}}:{{score}}<span class="givePoints">给分</span>

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

Template.scores.events({'点击 .click-me': 函数 () {控制台日志(这个);}});

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

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

  • Handlebars、Meteor 或介于两者之间的错误?
  • 关于模板的文档有点不完整?
  • 我完全误解了文档或不理解一些基本的东西关于 Meteor 或 Handlebars?

谢谢!

解决方案

这个视频解释了这些概念:

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

直接回答您的问题:

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

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

示例:

var context = {};<模板名称="withHelper">{{#with context}}//数据上下文是上下文对象{{/和}}var list = [ {name: "one"}, {name: "two"} ];<模板名称=列表">{{#每个列表}}{{ >listItem }}//数据上下文设置为列表项对象{{/每个}}

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

  • In the section of Documentation on template instances (docs.meteor/#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 (docs.meteor/#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:

www.eventedmind/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>

更多推荐

“this"的上下文在 Meteor 模板事件处理程序中(使用 Handlebars 进行模板化)

本文发布于:2023-11-24 02:11:03,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1623585.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:模板   上下文   事件   程序   quot

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!