2012-04-11 100 views
22

爲什麼此代碼顯示「0」?它不應該返回「1」嗎?流星 - 在客戶端啓動時使用集合

Messages = new Meteor.Collection("messages"); 

if (Meteor.is_client) { 
    Meteor.startup(function() {  
     alert(Messages.find().count()); 
    }); 
} 

if (Meteor.is_server) { 
    Meteor.startup(function() { 
     Messages.insert({text: "server says hello"}); 
    }); 
} 

如果我做了「Messages.find()。COUNT()」後,它返回1

+2

併發,歡迎它。 – Raynos 2012-04-11 05:09:06

+1

@Raynos它看起來不像一個併發問題。每次執行客戶端啓動處理程序時都會發生。 – pomber 2012-04-11 05:38:23

+0

這是一個併發問題,問題在於你同時在服務器和客戶端上運行兩件事情。並且您希望服務器一個神奇地完成第一個 – Raynos 2012-04-11 05:47:55

回答

37

默認情況下,當流星客戶端啓動時,它連接到服務器並訂閱您定義的任何Meteor.Collection中的文檔。這需要一些時間才能完成,因爲在建立服務器連接和接收文檔時總會有一些延遲。

Meteor.startup()在客戶端上很像jQuery中的$() - 它在客戶端DOM準備好後運行它的參數。它不是而是等待您的客戶的收藏從服務器接收他們的所有文檔。因此,您編寫代碼的方式,對find()的調用將始終運行得太早並返回0.

如果要等待直到首次從服務器下載集合之後才能運行代碼,則需要使用Meteor.subscribe()明確訂閱一個集合。 subscribe()需要一個回調,當初始文檔集在客戶端上時將執行回調。

參見:

meteor-publishmeteor-subscribe

+9

我很想看看如何做到這一點的代碼示例。 – 2012-05-27 20:12:46

+0

當使用'Meteor.subscribe()'時,我必須以某種方式關閉默認的「訂閱集合的所有文檔」行爲? – bijan 2012-06-20 16:57:54

+3

@bijan(或者對於其他擁有相同問題的人),是的,你需要刪除autopublish包:$ meteor remove autopublish。 – jtblin 2012-09-02 07:10:51

0

只是爲了跟進如何知道什麼時候一個集合準備在客戶端上使用的代碼示例。

如上所述@debergalis,你應該使用Meteor.subscribe方法 - 它接受一對夫婦的回調,尤其是onReady

例如:

if(Meteor.isClient){ 

    Meteor.subscribe("myCollection", { 

     onReady: function(){ 

      // do stuff with my collection 

     } 

    }); 

}