如何明确数据上下文?

时间:2015-12-04 19:46:50

标签: meteor

初学者问题:我正在研究Discover Meteor book, Chapter 3 on Templates。模板的这一行让我停下来:

<h3><a href="{{url}}">{{title}}</a><span>{{domain}}</span></h3>

这里发生的是{{domain}}表达式来自postItem模板助手,{{url}}{{title}}表达式来自postsList模板帮手。但是,通过查看模板,无法确定哪个表达式由哪个模板助手处理。我了解到,您可以使用模板中的this关键字使模板更加明确。但是,有没有一种方法可以在postItem模板中明确创建帮助程序?例如,我尝试这样做,但它不起作用:

Template.postItem.helpers({
  title: this.title,
  url: this.url,
  domain: function() {
    var a = document.createElement('a');
    a.href = this.url;
    return a.hostname;
  }
});

我不明白为什么这不起作用。我理解这可能会使代码更加冗长,但就个人而言,我更希望代码更明确,而不是模糊不清。

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

您对正在发生的事情的描述有点过时了。让我试着澄清一下发生了什么。

这两个模板是:

<template name="postsList">
  <div class="posts">
    {{#each posts}}
      {{> postItem}}
    {{/each}}
  </div>
</template>

<template name="postItem">
  <div class="post">
    <div class="post-content">
      <h3><a href="{{url}}">{{title}}</a><span>{{domain}}</span></h3>
    </div>
  </div>
</template>
  1. postList模板包含迭代器 {{#each posts}}
  2. 此迭代器从posts模板的postItem帮助程序获取其数据
  3. 帮助程序返回游标,这是对集合执行find()的结果。或者,这个助手可以返回一个对象数组。
  4. 游标被动意味着可以随时添加,删除或更改项目,而无需编写代码来更新DOM。魔法。
  5. 在迭代器中包含postItem模板。
  6. 对于迭代器的每次迭代,都会创建一个数据上下文,这是一个单独的对象。
  7. 在javascript中,当前数据上下文将位于this
  8. 在空格键中,只需将该字段的名称放在双花括号中即可访问对象中的任何字段:{{title}}
  9. 如果您想更明确,也可以使用{{this.title}}
  10. 有时,对象没有您需要显示的所有数据。您可能需要重新格式化现有字段,将它们组合起来,转换它们(例如:UTC到本地时间,$到£等等),或者从不同的集合中查找相关数据。在这些情况下,您需要帮助来返回额外的数据。

    以您正在显示的方式直接操作帮助程序中的DOM是不可取的。由于即使使用相同的数据上下文也可以重复调用帮助程序,因此最终可能会出现比预期更多的a个元素。

    实际上,当前数据上下文中的字段值与辅助值之间的区别对表示层并不重要。这不是阻碍Meteor发展的因素。出现的常见问题是您在标记中插入{{mything}}但忘记为其定义帮助程序,然后显示为空白。或者你相信你的对象有一个它没有的密钥,你也会得到一个空白。

答案 1 :(得分:1)

这是我在流星中使用Blaze明确数据上下文的首选方法。

你可以在这里看到一个有效的例子:

http://meteorpad.com/pad/rkybNCiKBpzEdcfHc/Template%20Parameters

我为每个子模板提供了一个明确的参数列表,如下所示:

{{> player name=this.name score=this.score}}

在此示例中,每个列表项只需要显示用户的姓名和分数。因此,子模板只获得两个变量作为其数据上下文,名称和分数,而不是其他任何变量 这有助于我调试问题并准确定义模板所需的字段。

//   Parent Template
Template.leaderboard.helpers({
  players: function () {
    return Players.find({}, { sort: { score: -1, name: 1 } });
  }
});

<template name="leaderboard">
  {{#each players}}
    {{> player name=this.name score=this.score}}
  {{/each}}
</template>


//   Child Template
<template name="player">
  <div>{{userName}} : {{userScore}}</div>
</template>

Template.player.helpers({
  userName: function() {
    return this.name;
  },
  userScore: function(){
    return this.score;
  }
});

在模板内部,如果数据上下文字段不可用或类型错误,也可以抛出错误。

当我开始使用Meteor时,我遇到了同样的问题,对于隐含数据上下文的想法,我觉得很尴尬。