2012-04-11 103 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 

     } 

    }); 

}