2013-05-27 6 views
8

Ich habe eine MongoDB mit einer großen "Nachrichten" Sammlung; alle Nachrichten, die zu einem bestimmten groupId gehören. Also mit einer Publikation wie diese begonnen haben:Wie kann ich mich explizit von einer Sammlung abmelden?

Meteor.publish("messages", function(groupId) { 
    return Messages.find({ 
    groupId: groupId 
    }); 
}); 

und ein Abonnement wie folgt aus:

Deps.autorun(function() { 
    return Meteor.subscribe("messages", Session.get("currentGroupId")); 
}); 

Das hat mich in Schwierigkeiten, weil zunächst currentGroupId undefiniert ist aber Schweller mongod die CPU aufbrauchen würde Nachrichten finden mit groupId == null (obwohl ich weiß, dass es keine gibt).

Jetzt habe ich versucht, die Veröffentlichung wie folgt zu umschreiben:

Meteor.publish("messages", function(groupId) { 
    if (groupId) { 
    return Messages.find({ 
     groupId: groupId 
    }); 
    } else { 
    return {}; // is this the way to return an empty publication!? 
    } 
}); 

und/oder das Abonnement zu umschreiben:

Deps.autorun(function() { 
    if (Session.get("currentGroupId")) { 
    return Meteor.subscribe("messages", Session.get("currentGroupId")); 
    } else { 
    // can I put a Meteor.unsubscribe("messages") here!? 
    } 
}); 

, die beide zunächst hilft. Sobald jedoch currentGroupId wieder undefiniert wird (weil der Benutzer zu einer anderen Seite navigiert), ist mongod immer noch damit beschäftigt, die Datenbank für die zuletzt abonnierte Adresse erneut anzufordern groupId. Wie kann ich mich von einer Veröffentlichung abmelden, so dass der Mongod nicht mehr abgefragt wird?

Antwort

5

einfach eine Bedingung zur Publikation ergänzt:

Meteor.publish("messages", function(groupId) { 
    if (groupId) { 
    return Messages.find({ 
     groupId: groupId 
    }); 
}); 

und das Abonnement zu halten:

Deps.autorun(function() { 
    return Meteor.subscribe("messages", Session.get("currentGroupId")); 
}); 

erledigt die Arbeit.

Es ist nicht erforderlich, die Veröffentlichung explizit zu stoppen. Schließlich wird die MongoDB nicht mehr abgefragt, nachdem die aktuell laufende Abfrage beendet wurde und noch eine weitere (die irgendwo im System in die Warteschlange eingereiht ist) ausgegeben wird.

+0

Leider habe ich keine Unterlagen gefunden, um diese Behauptung zu beweisen. Ein Hinweis würde sehr geschätzt werden. – Dejan

7

Gemäß der Dokumentation muss es http://docs.meteor.com/#publish_stop

this.stop sein() Anruf innerhalb der Funktion veröffentlichen. Stoppt das Abonnement dieses Kunden; Der OnError-Rückruf wird auf dem Client nicht aufgerufen.

So etwas wie

Meteor.publish("messages", function(groupId) { 
    if (groupId) { 
    return Messages.find({ 
     groupId: groupId 
    }); 
    } else { 
    return this.stop(); 
    } 
}); 

Und ich denke, auf der Client-Seite können Sie einfach Ihre entfernen, wenn/sonst wie in Ihrem ersten Beispiel

Deps.autorun(function() { 
    return Meteor.subscribe("messages", Session.get("currentGroupId")); 
}); 
+2

Ich denke, man einen Typ haben hier. 'Messages' hat keine' stop' Methode. Ich denke, es sollte stattdessen 'this.stop();' zurückgeben. – Dejan

+1

Ich glaube, Sie haben recht, nach dem Dokument ist der Aufruf stop() eine Methode von Meteor.publish, also habe ich es in this.stop() geändert. – Michael

+0

Jetzt ist die lustige Sache, dass das Weglassen des Aufrufs zu stop() das Verhalten nicht ändert. Schau dir meine Antwort an. – Dejan

0

in Ihrem Fall sollten Sie aufhören die autorun

gibt es ein Beispiel in der documentation

Ihre Autorun wird mit einem Parameter tatsächlich aufgerufen, dass Sie es zu stoppen erlaubt:

Deps.autorun(function (c) { 
    if (! Session.equals("shouldAlert", true)) 
    return; 

    c.stop(); 
    alert("Oh no!"); 
}); 
+0

Stoppen der 'Autorun' wird nicht helfen, weil ich Nachrichten wieder laden (d. H. Abonnieren) muss, sobald' currentGroupId' nicht mehr null ist. – Dejan

6

Ich fand es einfacher und geradlinig die .stop() Funktion auf dem Handler aufzurufen, die von der .subscribe() Aufruf zurückgegeben wird:

let handler = Meteor.subscribe('items'); 
... 
handler.stop(); 
Verwandte Themen