Spacebars {{#each}}如何运作?

时间:2015-06-21 12:26:38

标签: meteor spacebars

我不明白Spacebars {{#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
}

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

3 个答案:

答案 0 :(得分:2)

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

当您使用#each时,您可以为内部的任何内容创建新的数据上下文。你可以通过在你的助手上面放一个console.log(this)来检查这一点。

onCreatedonDestroyedonRendered中,this指向templateInstace()。因此,无论何时进行回调,都可以使用this.data来访问数据上下文。

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

在帮助程序中,this指向templateInstance().data,因此您只需拨打this即可。

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

答案 1 :(得分:1)

The {{#each}} template tag的特殊之处在于它改变了它的内在背景 实际上,每个模板都可以与一袋数据一起使用(例如帖子的标题和内容)。这个数据包在模板的拥有上下文中注册,可以在帮助者中使用this.someData引用,也可以在模板中命名({{someData}} )。

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

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

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

(秘诀是你必须以与能够阅读它的文本相同的频率闪烁,这就是为什么这个标签被用于如此愚蠢的长时间的原因)

{{#each}}允许您将模板的内部上下文更改为迭代的当前对象,从而只需访问您正在迭代的对象的内容。
我们假设您要创建一个博客帖子模板,其中显示了博客帖子列表:

{{#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}}块中的上下文与父项不同,而是作为博客文章,我们可以简单地通过名称来引用每个博客帖子字段!

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

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

blogPost模板需要博客帖子对象作为其上下文,我们为此上下文提供{{#each}}模板标记。

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

有关更多巫术,请参阅SpaceBars docs

答案 2 :(得分:1)

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

Matt K explained the rest pretty well.