2014-11-13 88 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