【问题标题】:Meteor helper called multiple times by single template variable单个模板变量多次调用 Meteor 助手
【发布时间】:2015-01-10 20:28:38
【问题描述】:
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 次(次数不同)。谁能解释这里发生了什么?我找不到对此的任何引用,在从模板上的多个 {{ }} 调用助手的情况下接受。还有什么办法阻止吗?最终我需要在推文被渲染之前一次性处理它们。

【问题讨论】:

    标签: javascript meteor


    【解决方案1】:

    当您执行查找流星时,会在您执行查找的集合上注册该模板助手的依赖项。因为这个依赖,meteor 会在每次修改集合时调用模板助手。

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

    所以该方法被多次调用,因为订阅会不断将新文档插入到您本地的 mongo 集合副本中,从而触发对模板帮助程序的新调用。

    解决这可能带来的任何问题的最佳模式是订阅帮助程序并在订阅documentation 上使用 ready 方法。 Ready 也是响应式的,因此当所有数据被拉入时,ready 将被更改为 true,并且将再次调用 helper。

      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}}
    

    【讨论】:

    • 好的,谢谢。我假设是这样的。有没有办法阻止它这样做? (假设服务器上的集合没有改变,这里就是这种情况)。在固定服务器和客户端集合之间以异步方式运行似乎很奇怪。
    • @kendlete 用一个关于如何处理流星订阅系统行为的示例更新了我的答案
    • Meteor.subscribe() 在文档中还有一个 onready 回调,可用于延迟插入更多代码,直到订阅准备好。这与 .ready() 不同,后者在订阅准备好时返回布尔值。可能比 Marco 的方法更麻烦。
    • 谢谢,非常有用。我还将if (ready) 放在帮助程序中以避免在订阅同步之前处理推文(它们将在呈现之前聚集)。
    猜你喜欢
    • 2015-03-28
    • 2015-11-23
    • 2014-01-30
    • 2016-05-26
    • 2016-06-10
    • 1970-01-01
    • 2015-01-06
    • 2019-04-07
    • 1970-01-01
    相关资源
    最近更新 更多