2012-04-11 13 views
22

Perché questo codice mostra "0"? Non dovrebbe restituire "1"?Meteor - Utilizzo della raccolta all'avvio del client

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"}); 
    }); 
} 

Se faccio la "Messages.find(). Count()" più avanti, restituisce 1.

+2

Concorrenza, benvenuto ad esso. – Raynos

+1

@Raynos Non sembra un problema di concorrenza. Succede ogni volta che viene eseguito il gestore di avvio del client. – pomber

+0

Si tratta di un problema di concorrenza, il problema è che si eseguono due cose contemporaneamente una sul server e una sul client. e si aspetta che il server si completi magicamente per primo – Raynos

risposta

37

Per impostazione predefinita, quando un client Meteor si avvia, si connette al server e sottoscrive documenti in qualsiasi Meteor.Collection definito. Ci vuole un po 'di tempo per completare, dal momento che c'è sempre un po' di ritardo nello stabilire la connessione al server e la ricezione dei documenti.

Meteor.startup() sul client è molto simile a $() in jQuery - esegue il suo argomento una volta che il DOM client è pronto. Fa non attendere che le raccolte del cliente ricevano tutti i loro documenti dal server. Quindi, nel modo in cui hai scritto il codice, la chiamata a find() verrà sempre eseguita troppo presto e restituirà 0.

Se si desidera attendere l'esecuzione del codice fino a quando non viene scaricato prima una raccolta dal server, è necessario utilizzare Meteor.subscribe() in iscriviti esplicitamente a una raccolta. subscribe() accetta una richiamata che verrà eseguita quando il set iniziale di documenti si trova sul client.

See:

meteor-publish e meteor-subscribe

+9

Mi piacerebbe vedere un esempio di codice su come farlo. –

+0

Quando si utilizza 'Meteor.subscribe()' devo in qualche modo disattivare il comportamento predefinito "sottoscrivi tutti i documenti di una raccolta"? – bijan

+3

@bijan (o per altri che hanno la stessa domanda), sì è necessario rimuovere il pacchetto autopublish: $ mete remove autopublish. – jtblin

0

Solo per follow-up con un esempio di codice di come sapere quando una collezione è pronto per l'uso sul client.

Come @debergalis descritto, si dovrebbe utilizzare l'approccio Meteor.subscribe - accetta un paio di callback, in particolare onReady

Ad esempio:

if(Meteor.isClient){ 

    Meteor.subscribe("myCollection", { 

     onReady: function(){ 

      // do stuff with my collection 

     } 

    }); 

} 
Problemi correlati