2014-11-13 40 views
7
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倍负载(次数变化)。任何人都可以解释这里发生了什么?我找不到任何对此的引用,接受在模板上从多个{{}}调用助手的情况。还有什么方法来阻止它?最终,我需要在呈现之前一次处理推文。

回答

7

当你做一个发现流星注册该模板助手的依赖关系在你找到的集合上。因为这种依赖关系,meteor会为集合的每一个修改都调用模板助手。

如果您还没有订阅,您的mongo集合的客户端副本中没有加载任何数据。 只有当你打电话订阅时,流星才会开始从服务器拉入数据。

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

最好的模式,以解决这个问题可能会出现的任何问题是通过订阅帮助者和使用就绪方法订阅documentation。就绪也是反应性的,所以当所有数据被拉入准备状态时,就会变成真并且帮助器将被再次调用。

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

好,谢谢。我假设了这样的事情。有没有办法阻止它这样做? (假设服务器上的集合没有改变,这里就是这种情况)。在固定服务器和客户端集合之间进行同步异步运行似乎很奇怪。 – kendlete

+0

@kendlete更新了我的答案,举例说明了如何处理流星订阅系统的行为 –

+0

Meteor.subscribe()在文档中也有一个onready回调函数,可以用来延迟插入更多的代码,直到订阅为止准备。这与.ready()不同,如果订阅已准备就会返回布尔值。可能比Marco的方法更麻烦一点。 – Paul