2015-05-17 25 views
6

I in Meteor.users System definiert Sammlung das Profil Feld bin mit Informationen über die letzte Nachricht Benutzer auf jedem Kommunikationskanal mit der folgenden Struktur zu lesen, zu speichern:Wie auf Meteor.users warten, wenn Profilfeld Ändern

profile : { 
    lastMsgRead : [ 
     {channelId: 'YYEBNEI7894K', messageCreatedAt: '14578970667"} 
     {channelId: 'GERYUE789774', messageCreatedAt: '14578999845"} 
    ] 
} 

Ich entdeckte, dass das Lesen von lastMsgRead-Feld fehlschlägt, weil auf dem Client das Array zum Zeitpunkt des Lesens noch leer ist. ich richtig dieses Feld an den Client über veröffentlichen:

Meteor.publish(null, function() { 
    return Meteor.users.find({}, {fields: {_id: 1, username: 1, emails: 1, profile :1}}); 

und ich seinen Wert von einer Client-Bibliothek lesen im lib-Verzeichnis befinden, auf diese Weise:

var chHistory = Meteor.user().profile.lastMsgRead; 

mein Code debuggen es sieht aus wie Die Änderungen, die ich an dem Profilfeld vorgenommen habe, wurden zum Zeitpunkt des Lesens nicht an alle Clients weitergegeben. Also muss ich auf das Abonnement warten Meteor.users wird fertig, aber ich habe kein Handle ─ Sie bekommen dies automatisch aus dem Framework.

Wie kann ich warten, bis das Meteor.users-Abonnement fertig ist?

+0

Würde eine Antwort auf Ihr spezifisches Problem (stellen Sie sicher, dass das Unterfeld ausgefüllt ist, bevor Sie damit arbeiten) passen Sie? Ich bin mir nicht sicher, ob Ihre aktuelle Frage (ob ein unbenanntes Abonnement bereit ist) mit etwas anderem zu verantworten ist als "Meteor bietet derzeit keine solche Funktion". –

Antwort

6

Weil Meteor Ihnen kein Handle für das Abonnement des aktuellen Benutzers bietet, gibt es keine offensichtliche Möglichkeit, auf die Daten zu warten. Hier sind einige Möglichkeiten:

Gebrauch eine Wache

Der typische Weg, dieses Problem zu handhaben ist guards, um Ihren Code hinzuzufügen.In Ihrer Vorlage (n), die dieses Problem auftritt Sie so etwas wie schreiben konnte:

var user = Meteor.user(); 
var lastMsgRead = user && user.profile && user.profile.lastMsgRead; 

Wenn Sie Sie diesen Code viel schreiben finden, könnten Sie es ausklammern in eine gemeinsame Funktion:

var extractProfileValue = function(key) { 
    var user = Meteor.user(); 
    return user && user.profile && user.profile[key]; 
}; 

Und es wie folgt verwenden:

var lastMsgRead = extractProfileValue('lastMsgRead'); 

zeigen ein Spinner

Sie können für die Existenz der das Profil des Benutzers testen in der Vorlage selbst:

<template name='myTemplate'> 
    {{#unless currentUser.profile}} 
    // show spinner or loading template here 
    {{else}} 
    // rest of template here 
    {{/unles}} 
</template> 

Wenn Sie diese Erfahrung auf allen Ihren Seiten wollen, können Sie es zu Ihrem Layout-Vorlage hinzufügen könnte (n).

redundante Verleger

WARNUNG: Ich habe nicht versucht

Eine Möglichkeit, einen Benutzer Abonnement Griff zu bekommen ist nur einen redundanten Verlag hinzuzufügen und abonnieren Sie es:

Meteor.publish('myProfile', function() { 
    return Meteor.users.find(this.userId, {fields: {profile: 1}}); 
}); 

Dann in Ihrem Router:

waitOn: function() { 
    return Meteor.subscribe('myProfile'); 
} 
+0

Danke! Ich versuche die ** redundante Herausgeber ** Option, aber ich habe ein paar Fragen für Sie: (a) wäre es nicht besser, das Profilfeld der Benutzer Sammlung zu vermeiden? Ich habe von seinem Verhalten gehört, dass es bald geändert wird, also wäre vielleicht eine neue Profiles-Sammlung besser; (b) Ich muss sicher sein, dass die Sammlung in einer Bibliothek (/ lib-Verzeichnis) synchronisiert ist. Kann ich 'handle = Meteorsubscribe ('myProfile');' in dieser Bibliothek aufrufen und dann nach 'handle.ready()' suchen, bevor 'Profiles.find()'? – massimosgrelli

+0

(a) Ich habe diesbezüglich kein Insiderwissen. Ich vermute, dass kurzfristig etwas passieren könnte, wo die Berechtigungsregeln für 'profile' modifiziert werden (momentan kann es auf dem Client standardmäßig aktualisiert werden, sollte aber wahrscheinlich nicht sein). Ich bezweifle, dass MDG das Feld in absehbarer Zeit fallen lassen würde. (b) Ja, es ist ein normales Abonnement, daher sehe ich keinen Grund, warum das nicht funktionieren würde. –

-1

Sie müssen http://docs.meteor.com/#/full/meteor_user erneut lesen.

Auf dem Client ist dies die Teilmenge der Felder im Dokument, die vom Server veröffentlicht werden (andere Felder sind auf dem Client nicht verfügbar). Standardmäßig veröffentlicht der Server den Benutzernamen, die E-Mails und das Profil (vom Benutzer beschreibbar). Weitere Informationen zu den Feldern in Benutzerdokumenten finden Sie unterMeteor.users.

Sie können einen Helfer hinzufügen, der die Daten zurückgibt.

Ich würde auch Ihre Veröffentlichung entfernen, wie es bereits durch das Framework behandelt wird.

Meteor.user(). Profile.blah

+0

Es werden nicht alle Felder veröffentlicht, die restlichen Felder müssen Sie selbst veröffentlichen. –

+0

Wenn Sie Meteor.user(). Profile.fullname haben, wird es veröffentlicht. Überprüfen Sie es vor der Abstimmung – Felix

+0

Einige Felder sind veröffentlicht und andere nicht. Wenn Sie Ihre eigenen Felder hinzufügen, müssen Sie sie veröffentlichen. –

0

Du Publikation macht zu viele unnötigen Daten. Du solltest nur veröffentlichen, was du brauchst. Meteor.user() gibt ein Benutzerobjekt zurück, wenn ein Benutzer angemeldet ist. In Ihrer Publikation null filtern Sie mit this.userId. Sie können auf diese Publikation auf Vorlagenebene warten oder den Iron Router verwenden.

0

Da Sie eine Null- oder "automatische" Veröffentlichung verwenden, gibt es eine wirklich einfache Lösung für dieses Problem und das Hinzufügen von Meteorspuren: Fast-Render zu Ihrer Anwendung. Es sendet alle automatisch veröffentlichten Daten mit dem anfänglichen HTML der App, so dass es sofort nach dem Laden der Seite verfügbar ist.