Meteor助手通过单个模板变量多次调用

时间:2014-11-13 16:05:46

标签: javascript meteor

Tweets = new Meteor.Collection('tweets');

if (Meteor.isClient) {

  Meteor.subscribe('tweets');

  Template.Panel.helpers({
    items: function() {
      var days_tweets = Tweets.find();
      console.log(days_tweets.count());
      return days_tweets;
    });
  }

if (Meteor.isServer) {
  Meteor.publish('tweets', function() {
    return Tweets.find({}, {limit: 1000});
  });

模板:

<body>
<h1>This is a list of tweets</h1>
  {{> Panel}}
</body>

<template name="Panel">
<h2>A list of tweets sorted by size</h2>
    {{#each items}}
        <p>item</p>
    {{/each}}
</template>

页面加载时控制台输出:

Tweet count:  0
Tweet count:  129
Tweet count:  272
Tweet count:  366
Tweet count:  457
Tweet count:  547
Tweet count:  672
Tweet count:  814
Tweet count:  941
Tweet count:  1000

因此辅助函数在页面加载时会触发10次(次数变化)。谁能解释一下这里发生了什么?我无法找到对此的任何引用,在模板上从多个{{}}调用帮助程序的情况下接受。还有什么方法可以阻止它吗?最终我需要在呈现之前一次性处理推文。

1 个答案:

答案 0 :(得分:7)

当您执行find meteor时,会在您找到的集合上注册该模板助手的依赖项。由于该依赖性,meteor将为集合的每次修改调用模板助手。

如果您尚未订阅,则mongo集合的客户端副本中不会加载任何数据。 只有当你调用subscribe时,流星才会开始从服务器中提取数据。

因此,该方法被多次调用,因为subscribe不断将新文档插入到mongo集合的本地副本中,从而触发对模板助手的新调用。

解决此问题的最佳模式是通过订阅帮助程序并在订阅documentation上使用ready方法。 Ready也是反应性的,所以当所有数据被拉入就绪时将被改为true并且将再次调用帮助器。

  Template.Panel.helpers({
      items: function() {
          var ready = Meteor.subscribe('tweets').ready();
          var days_tweets = Tweets.find();

          return {
              data: days_tweets,
              ready: ready
          };
      });
  }

模板本身:

{{#with items}}
     {{#if ready}}
         {{#each data}}
             <p>item</p>
         {{/each}}
     {{else}}
         Show a spinner or whatever
     {{/if}}
{{/with}}