2015-05-17 28 views
6

Sto utilizzando il campo del profilo nel sistema di raccolta Meteor.users definito per memorizzare le informazioni su l'ultimo utente messaggio letto su tutti i canali di comunicazione con la seguente struttura:Come aspettare Meteor.users quando si cambia profilo campo

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

Ho scoperto che la lettura del campo lastMsgRead fallisce a causa del fatto che sul client la matrice è ancora vuota al momento della lettura. Ho correttamente pubblicare questo campo per il cliente attraverso:

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

e ho letto il suo valore da una libreria client si trova nella directory lib, in questo modo:

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

Debug mio codice sembra le modifiche apportate al campo del profilo non sono state propagate a tutti i client nel momento in cui li ho letti. Quindi ho bisogno di aspettare che la sottoscrizione di Meteor.users sia pronta, ma non ho il suo handle ─ l'hai ottenuta automaticamente dal framework.

Come posso aspettare che l'abbonamento a Meteor.users sia pronto?

+0

Una risposta che risolva il problema specifico (assicurandoti che il sottocampo venga compilato prima di utilizzarlo) ti soddisfa? Non sono sicuro che la tua domanda corrente (assicurandoti che un abbonamento senza nome sia pronto) è responsabile di qualcos'altro oltre a "Meteor non fornisce attualmente tale funzione". –

risposta

6

A causa di meteore non ti forniscono una maniglia per la sottoscrizione dell'utente corrente, non v'è un modo ovvio per attendere sui dati. Qui ci sono alcune opzioni:

uso una guardia

Il modo tipico per gestire questo problema è quello di aggiungere guards al codice.Nel modello (s), che stanno vivendo questo problema si potrebbe scrivere qualcosa di simile:

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

Se si trova si scrive che il codice molto, si potrebbe fattore fuori in una funzione comune:

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

e usarlo in questo modo:

var lastMsgRead = extractProfileValue('lastMsgRead'); 

mostrano un filatore

È possibile verificare l'esistenza di profilo dell'utente nel modello stesso:

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

Se si desidera che questa esperienza su tutte le pagine, è possibile aggiungere al vostro modello di layout (s).

editore ridondante

ATTENZIONE: non ho provato questa

Un modo per ottenere la maniglia di sottoscrizione di un utente è solo per aggiungere un editore ridondante e abbonarsi:

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

Quindi nel router:

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

Grazie! Sto provando l'opzione ** ridondante editore **, ma ho un paio di domande per te: (a) non sarebbe meglio evitare il campo profilo della raccolta utenti? Ho sentito il suo comportamento che cambierà presto, quindi forse una nuova collezione di Profili sarebbe migliore; (b) Devo essere sicuro che la collezione sia sincronizzata in una libreria (directory/lib). Posso chiamare 'handle = Meteor.subscribe ('mioProfilo');' in quella libreria e quindi controllare 'handle.ready()' prima di citare 'Profiles.find()'? – massimosgrelli

+0

(a) Non ho alcuna conoscenza approfondita su questo. Sto indovinando che a breve termine potrebbe accadere qualcosa in cui le regole di autorizzazione sono state modificate per 'profile' (in questo momento può essere aggiornato sul client di default ma probabilmente non dovrebbe essere). Dubito che MDG lascerebbe cadere il campo nel minor tempo possibile. (b) Sì, è un abbonamento normale, quindi non vedo alcun motivo per cui ciò non funzioni. –

-1

È necessario leggere nuovamente http://docs.meteor.com/#/full/meteor_user.

Sul client, questo sarà il sottoinsieme dei campi nel documento che vengono pubblicati dal server (altri campi non saranno disponibili sul client). Di default il server pubblica username, e-mail e profilo (scrivibile dall'utente). SeeMeteor.users per ulteriori informazioni sui campi utilizzati nei documenti dell'utente.

È possibile aggiungere un helper che restituirà i dati.

Vorrei anche rimuovere la pubblicazione poiché è già stata gestita dal framework.

Meteor.user(). Profile.blah

+0

Non pubblicherà tutti i campi, i campi rimanenti che devi pubblicare tu stesso. –

+0

Se si dispone di Meteor.user(). Profile.fullname, viene pubblicato. Controllalo prima di andare a votare – Felix

+0

Alcuni campi sono pubblicati e altri no. Se aggiungi i tuoi campi, devi pubblicarli. –

0

È pubblicazione espone troppi dati inutili. Dovresti pubblicare solo ciò di cui hai bisogno. Meteor.user() restituisce un oggetto utente se un utente ha effettuato l'accesso. Nella pubblicazione null si filtra utilizzando this.userId. Puoi aspettare su questa pubblicazione a livello di modello o utilizzando Iron Router.

0

Poiché si utilizza una pubblicazione nulle o "automatica", esiste una soluzione molto semplice per questo problema e quella di aggiungere meteorhacks: rendering veloce alla propria applicazione. Invierà tutti i dati pubblicati automaticamente con l'html iniziale dell'app in modo che sia immediatamente disponibile al caricamento della pagina.