2012-04-11 6 views
22

Warum zeigt dieser Code "0"? Sollte es nicht "1" zurückgeben?Meteor - Verwendung der Sammlung beim Client-Start

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

Wenn ich die "Messages.find(). Count()" später kehrt 1.

+2

Concurrency, willkommen zu. – Raynos

+1

@Raynos Es sieht nicht wie ein Nebenläufigkeitsproblem aus. Dies geschieht jedes Mal, wenn der Client-Start-Handler ausgeführt wird. – pomber

+0

Es ist ein Nebenläufigkeitsproblem, das Problem ist, dass Sie zwei Dinge gleichzeitig auf dem Server und einem auf dem Client ausführen. und Ihr erwartet den Server man magisch zuerst fertig – Raynos

Antwort

37

standardmäßig, wenn ein Meteor-Client startet, wird eine Verbindung mit dem Server und abonniert Dokumente in jedem Meteor.Collection Sie definiert. Das dauert einige Zeit, da beim Herstellen der Serververbindung und beim Empfangen von Dokumenten immer eine gewisse Verzögerung auftritt.

Meteor.startup() auf dem Client ist sehr ähnlich wie $() in jQuery - es führt sein Argument, sobald das Client-DOM bereit ist. Es tut nicht warten Sie auf die Sammlungen Ihres Kunden, um alle ihre Dokumente vom Server zu erhalten. So wie Sie den Code geschrieben haben, wird der Anruf zu find() immer zu früh ausgeführt und 0 zurückgeben.

Wenn Sie Code ausführen möchten, bis eine Sammlung zuerst vom Server heruntergeladen wird, müssen Sie Meteor.subscribe() zu verwenden explizit eine Sammlung abonnieren. subscribe() nimmt einen Rückruf, der ausgeführt wird, wenn sich die erste Gruppe von Dokumenten auf dem Client befindet.

See:

meteor-publish und meteor-subscribe

+9

Ich würde gerne ein Codebeispiel sehen, wie man das macht. –

+0

Bei Verwendung von 'Meteorsubscribe()' muss ich irgendwie das Standardverhalten "Alle Dokumente einer Sammlung abonnieren" deaktivieren? – bijan

+3

@bijan (oder für andere, die dieselbe Frage haben), ja, Sie müssen das Autopublish-Paket entfernen: $ meteor remove autopublish. – jtblin

0

nur mit einem Code Beispiel zu folgen, wie zu wissen, wann eine Sammlung bereit ist, auf dem Client zu verwenden.

Wie @debergalis beschrieben, sollten Sie den Meteor.subscribe Ansatz verwenden - es ein paar Rückrufe akzeptiert, insbesondere onReady

Zum Beispiel:

if(Meteor.isClient){ 

    Meteor.subscribe("myCollection", { 

     onReady: function(){ 

      // do stuff with my collection 

     } 

    }); 

}