2013-02-28 1 views
13

Ich möchte so bald wie möglich nach dem Laden der Seite eine Meteor Collection-Abfrage durchführen. Das erste, was ich versuchte, war so etwas wie dieses:Meteor: Wie kann ich feststellen, wann die Datenbank fertig ist?

Games = new Meteor.Collection("games"); 
if (Meteor.isClient) { 
    Meteor.startup(function() { 
    console.log(Games.findOne({})); 
    }); 
} 

Dies funktioniert nicht, wenn (er druckt „undefined“). Die gleiche Abfrage funktioniert einige Sekunden später, wenn sie von der JavaScript-Konsole aus aufgerufen wird. Ich nehme an, dass es eine Art Verzögerung gibt, bevor die Datenbank fertig ist. Also, wie kann ich sagen, wenn diese Abfrage erfolgreich ist?

Meteor Version 0.5.7 (7b1bf062b9) unter OSX 10.8 und Chrome 25.

+0

Ort, wo ich eigentlich diese verwenden müssen? Wäre es möglich, den Anruf in eine "Vorlage" zu stellen? – Swadq

+0

Nein, ich möchte einen URL-Parameter lesen und den Browser eventuell umleiten, wenn er nicht in der Datenbank gefunden wird. –

+0

Ziemlich viel ein Duplikat von [Loader während Meteor Sammlung lädt angezeigt] (http://stackoverflow.com/questions/12879762/displaying-loader-while-meteor-collection-loads) –

Antwort

17

Sie sollten zunächst publish die Daten vom Server.

Führen Sie auf dem Client die Sammlungsabfragen erst aus, nachdem die Daten vom Server geladen wurden. Dies kann durch Verwendung einer reaktiven Sitzung innerhalb der subscribe Anrufe erfolgen.

if (Meteor.isClient) { 
    Meteor.startup(function() { 
    Session.set('data_loaded', false); 
    }); 

    Meteor.subscribe('default_db_data', function(){ 
    //Set the reactive session as true to indicate that the data have been loaded 
    Session.set('data_loaded', true); 
    }); 
} 

Wenn Sie nun Sammlung Abfragen durchführen, können Sie überprüfen, ob die Daten oder nicht geladen ist:

if(Session.get('data_loaded')){ 
    Games.find({}); 
} 

Hinweis:autopublish Paket entfernen, veröffentlicht es alle Ihre Daten standardmäßig die Client und ist eine schlechte Praxis.

Um es zu entfernen, führen Sie $ meteor remove autopublish für jedes Projekt aus dem Stammprojektverzeichnis.

+0

Ich ging mit diesem Ansatz und die Dinge funktionierten. Der Rückruf zu Meteorsubscribe wird aufgerufen, wenn die Datenbank bereit ist. –

+3

Gibt es einen Grund, warum Sie hier kein Subskriptions-Handle und die Methode 'ready()' verwenden? –

+1

Sehr seltsame Lösung! Auf meinem eigentlichen Meteor (0.6.6.2) macht diese Zeile "this.ready()" völlig entgegengesetzte Sache - feuert das Event auf meinem Client ab, bevor echte Daten bereit sind. Wenn Sie es eingeben, können Sie den Rückruf verwenden, wie @ Jonatan sagt. – peko

0

Sie könnten überprüfen, wenn ein Ergebnis schließlich zurückgegeben, wenn Sie wissen, dass Ihre Spiele Sammlung nie leer ist:

Meteor.autorun(function() { 
    if(Games.findOne() && !Session.get("loaded")) { 
     Session.set("loaded",true); 

     //Its ready.. 
     console.log(Games.findOne({})); 
    } 
}); 

Sie können dies auch in Ihren Vorlagen verwenden:

Client-js:

Template.home.isReady = function() { return Session.get("loaded") }; 

Html

<template name="home"> 
    {{#if isReady}} 
     Yay! We're loaded!! 
    {{else}} 
     Hold an a second 
    {{/if}} 
</template> 
+0

Update 2015: jetzt haben wir [Template.instance() .subscriptionsReady()] (http://stackoverflow.com/questions/12879762/displaying-loader-while-meteor-collection-loads/12880255#12880255). –

8

Verwenden DDP._allSubscriptionsReady() (Meteor 0.7)

+4

Update 2015: Jetzt haben wir die offizielle [Template.instance() .subscriptionsReady()] (http://stackoverflow.com/questions/12879762/displaying-loader-while-meteor-collection-loads/12880255#12880255). –

6

Ab Meteor 1.0.4 gibt es einen Helfer, der Ihnen genau sagt, wann ein bestimmtes Abonnement ist bereit: Template.instance().subscriptionsReady().

Da diese Frage ein Duplikat ist, überprüfen Sie bitte meine Antwort in der ursprünglichen Frage, Displaying loader while meteor collection loads.

+0

Was ist Instanz()? – malhal

+0

@ Malhal es bezieht sich auf die Vorlage. Aus der [docs] (http://docs.meteor.com/api/templates.html#Template-instance): Die Vorlageninstanz, die dem aktuellen Vorlagen-Helper, Event-Handler, Callback oder Autorun entspricht. Wenn es keinen gibt, null. –

0

Hier ist ein weiterer Leckerbissen an Informationen für diejenigen, die Benutzer-ID oder einen Teil der in der Meteor.users-Datenbank gespeicherten Benutzerinformationen verwenden. Wenn die Seite zuerst die Meteor-Subscribe lädt, die im Hintergrund läuft, ist sie möglicherweise nicht vollständig. Wenn Sie versuchen, eine Verbindung mit einer anderen Datenbank herzustellen, um diese Abfrage durchzuführen, werden die Informationen nicht abgerufen. Dies liegt daran, dass Meteor.user() immer noch Null ist;

Der Grund, wie oben gesagt, ist, weil die tatsächliche Meteor Benutzer Sammlung nicht durch Ziehen der Daten bekommen hat.

Einfache Möglichkeit, damit umzugehen.

Meteor.status().connected

Dies wird wahr oder falsch zurückgeben, Sie wissen zu lassen, wenn die Meteor.user abholbereit ist. Dann können Sie über Ihr Geschäft weitermachen.

Ich hoffe, dass dies jemand hilft, ich war dabei, meine Haare herauszuziehen und herauszufinden, wie man den Status überprüfen kann. Das war nach dem Herausfinden der Meteor User Collection selbst noch nicht geladen.

+0

Vielleicht missverstehe ich, was 'Meteor.status(). Connected 'darstellt, aber es gibt einen Blitz, wenn' verbunden 'wahr ist, aber' Meteor.user() 'ist null. –

1

Sie können auch Vorlagen Ebene Abonnements tun:

Template.name.onCreated(function(){ 
var self = this; 

this.autorun(function(){ 

const db = this.subscribe('publicationname', [,args]); 

if(db.isReady()){ 
"You'll know it's ready here" .. do what you need. 
} 
}); 
}) 

Dies macht es einfacher zu in der Vorlage zu kennen. Sie können nur {{# if Template.subscriptionsReady}} rufen {{else}} Ladebildschirm
sein kann {{/ if}}