空格键 {{#each}} 是如何工作的?

How does Spacebars {{#each}} work?

我不明白空格键 {{#each}} 模板标签会发生什么。
例如我有一个简单的事件代码:

'click #player': function(){
  var playerId = this._id;
  Session.set('selectedPlayer', playerId);
  Session.set('selectedPlayerName', this.name);
}

模板中相应的代码:

{{#each player}}
    <a href="#" id="player" class="{{selectedClass}}"></a>
{{/each}}

最后是这个帮手:

'selectedClass': function(){
  return this._id
}

事件处理程序和辅助函数如何知道引用了哪些列表项?

在 Meteor 中,您已经获得了您创建的所有模板。每次渲染模板时,都会给它一个数据上下文,这是一种创建新功能范围的奇特方式。该数据上下文存储在 templateInstance().data.

当您使用 #each 时,您会为其中的任何内容创建一个新的数据上下文。您可以通过在 return.

上方的助手中放置 console.log(this) 来检查这一点

onCreatedonDestroyedonRendered中,this指向templateInstace()。因此,每当您处于回调中时,请使用 this.data 访问数据上下文。

events 回调中,您有 2 个参数:event, template。这里,template 也指向 templateInstance()

在助手中,this 指向 templateInstance().data,因此您只需调用 this

空格键不是魔法,它只是让 JS 看起来像 HTML 的一种方式。假设您的模板存储在 views/templates.html 中,请查看 .meteor/local/build/programs/web.browser/app/client/views/template.templates.html,这一切都会有意义。

The {{#each}} template tag的特殊之处在于它改变了它的内部上下文。
事实上,每个模板都可以使用一袋数据(例如 post 的标题和内容)。这包数据在模板的 own 上下文中注册,可以在 helpers 中使用 this.someData 引用,或者在模板中简单地命名它 ({{someData}}) .

其他模板标签,例如 {{#if}},不会更改其中模板的上下文。您可以在博客 post 模板中键入,该模板接收博客 post object 作为数据:

<h3>{{title}}</h3>
<p>{{content}}</p>

{{#if userIsSecretAgent}}
  <blink>{{secretData}}</blink>
{{/if}}

(秘密是你必须以与文本相同的频率眨眼才能阅读它,这就是为什么这个标签被使用了这么长时间的愚蠢)


{{#each}} 允许您将模板的内部上下文更改为迭代的当前 object,因此只需访问您正在迭代的 object 的内容。
假设您想制作一个博客 posts 模板,该模板显示博客列表 posts:

{{#each blogPosts}}
  <!-- Here, how do you gain access to each title, each content, ..? -->
  <!-- Well, the context has changed! -->
  <!-- Now we can directly access each datum of the iterable through the context -->

  <!-- The result simply becomes: -->
  <h3>{{title}}</h3>
  <p>{{content}}</p>

  {{#if userIsSecretAgent}}
    <blink>{{secretData}}</blink>
  {{/if}}
{{/each}}

{{#each}} 块中的上下文与 parent 不同,而是一个博客 post,我们可以简单地引用每个博客 post按名称命名的字段!

但是现在我们在重复代码。重用我们以前的模板不是很好吗?

{{#each blogPosts}}
  {{> blogPost}}
{{/each}}

blogPost 模板需要博客 post object 作为上下文,我们使用 {{#each}} 模板标签提供此上下文。

助手的工作方式相同,只是您必须在其中键入 this.titlethis.content。您还必须在某些地方使用 Template.instance() 来引用模板(而不是 this)。

查看SpaceBars docs了解更多魔法。

由此产生的 HTML 无效,因为多个元素具有相同的 id 属性。事件处理程序很容易解释。 event-map 中的键被分成 event-type 和可选的 event-targetevent-target 被传递给 jQuery,它容忍 id 的无效使用。因此 jQuery 将事件监听器添加到所有具有 id player.

的元素