2012-04-11 6 views
22

Pourquoi ce code affiche-t-il "0"? Ne devrait-il pas retourner "1"?Meteor - Utilisation de la collection au démarrage du 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"}); 
    }); 
} 

Si je fais le "Messages.find(). Count()" plus tard, il retourne 1.

+2

Concurrency, bienvenue à lui. – Raynos

+1

@Raynos Cela ne ressemble pas à un problème de concurrence. Cela se produit chaque fois que le gestionnaire de démarrage du client est exécuté. – pomber

+0

Il s'agit d'un problème de simultanéité, le problème est que vous exécutez deux choses simultanément sur le serveur et un sur le client. et vous attendez que le serveur finisse magiquement en premier – Raynos

Répondre

37

Par défaut, lorsqu'un client Meteor démarre, il se connecte au serveur et est abonnée à documents dans tout Meteor.Collection vous avez défini. Cela prend un certain temps, car il y a toujours un certain retard dans l'établissement de la connexion au serveur et la réception des documents.

Meteor.startup() sur le client ressemble beaucoup à $() dans jQuery - il lance son argument une fois que le client DOM est prêt. Il ne pas attendre les collections de vos clients pour recevoir tous leurs documents du serveur. Ainsi, de la façon dont vous avez écrit le code, l'appel à find() sera toujours exécuté trop tôt et renverra 0.

Si vous voulez attendre que le code ait été téléchargé pour la première fois depuis le serveur, vous devez utiliser Meteor.subscribe() pour souscrire explicitement à une collection. subscribe() prend un rappel qui s'exécutera lorsque l'ensemble initial de documents est sur le client.

Voir:

meteor-publish et meteor-subscribe

+9

J'aimerais voir un exemple de code sur la façon de faire cela. –

+0

Lorsque vous utilisez 'Meteor.subscribe()' dois-je désactiver le comportement par défaut "s'abonner à tous les documents d'une collection"? – bijan

+3

@bijan (ou pour les autres qui auraient la même question), oui vous devez supprimer le paquet autopublish: $ meteor remove autopublish. – jtblin

0

Juste pour suivre avec un exemple de code de la façon de savoir quand une collection est prêt à être utilisé sur le client.

Comme @debergalis décrit, vous devez utiliser l'approche Meteor.subscribe - il accepte quelques callbacks, notamment onReady

Par exemple:

if(Meteor.isClient){ 

    Meteor.subscribe("myCollection", { 

     onReady: function(){ 

      // do stuff with my collection 

     } 

    }); 

} 
Questions connexes