2012-05-20 2 views
41

Ho provato to understand this post regarding this concept, tuttavia, non riesco a ottenerlo. Ho la seguente configurazione semplice:Come ottenere Meteor.Call per restituire il valore per il modello?

/server/test.js 
Meteor.methods({ 
    abc: function() { 
    var result = {}; 
    result.foo = "Hello "; 
    result.bar = "World!"; 
    return result; 
    } 
}); 

/client/myapp.js 
var q = Meteor.call('abc'); 
console.log(q); 

Tale struttura torna alla console undefined.

Se cambio il file myapp.js a:

Meteor.call('abc', function(err, data) { 
    !err ? console.log(data) : console.log(err); 
} 

ricevo il Object nella mia console.

Idealmente questo è quello che mi piacerebbe essere in grado di fare, ma non funziona, affermando nella console: Cannot read property 'greeting' of undefined

/client/myapp.js 
var q = Meteor.call('abc'); 

Template.hello.greeting = function() { 
    return q.foo; 
} 

Qualsiasi aiuto nel passare i dati dall'oggetto server nel modello sarebbe molto apprezzato. Sto ancora imparando JavaScript & Meteor.

Grazie!

risposta

77

Da the Meteor.call documentation:

Sul client, se non si passa una richiamata e non sei all'interno di uno stub, chiamata tornerà indefinita, e si avrà modo di ottenere il valore di ritorno del metodo. Questo perché il client non ha fibre, quindi non c'è in realtà alcun modo in cui possa bloccare l'esecuzione remota di un metodo.

Quindi, ti consigliamo di farlo in questo modo:

Meteor.call('abc', function(err, data) { 
    if (err) 
    console.log(err); 

    Session.set('q', data); 
}); 

Template.hello.greeting = function() { 
    return Session.get('q').foo; 
}; 

Questo sarà reattivo aggiornare il modello una volta che i dati sono disponibili.

+1

Ciao Tom, grazie mille per la vostra risposta rapida! Ho dovuto chiudere la tua funzione Meteor.call con ');' e aggiungere un punto e virgola alla fine della funzione 'Template.hello.greeting' per farlo funzionare (se volessi modificare il tuo codice). Grazie ancora per il vostro aiuto! – rs77

+0

Oh woops, piccoli errori, risposta corretta. Buon divertimento ... :) –

+1

Ciao Tom, domanda veloce - se non ci si aspetta che i dati cambino a lungo termine, c'è un modo per farlo senza dover usare l'oggetto di sessione? Sembra molto dispendioso e prolisso altrimenti, con l'aumentare del numero di variabili. Grazie. –

1

Ciò accade perché Npm.require ha un comportamento Async. Questo è il motivo per cui devi scrivere una richiamata per Meteor.call.

Ma c'è una soluzione, basta usare install(mrt add npm) e si otterrà una funzione denominata Meteor.sync(//...) con questo si può fare entrambi i giochi: sincronizzazione e async nel vostro Meteor.call().

Riferimento: http://www.sitepoint.com/create-a-meteor-app-using-npm-module/

0

È possibile ottenere il valore di ritorno di un metodo Meteor per l'uso in un modello utilizzando un reactive variable. Controlla il working demonstration on Meteorpad

+0

L'esempio in Meteorpad non funziona per me. Inoltre, la distribuzione dell'esempio funziona ... una specie di. Cioè, funziona una volta, ma, per me, il metodo non viene chiamato quando le informazioni sottostanti vengono aggiornate. – MastaBaba

+1

I metodi non sono di per sé reattivi, ma possono essere richiamati da un contesto reattivo come Template.instance(). Autorun() o template helper. –

0

Sono andato per una soluzione ghetto. Ma funziona per me, che è ciò che conta, per me. Di seguito è riportato il mio codice, che, nel concetto, penso, risolve il problema dell'OP.

Nel main.js del cliente:

Meteor.setInterval(function() { 
    confirmLogin(); 

}, 5000); 

Questo esegue la funzione confirmLogin() ogni cinque secondi.

La funzione confirmLogin (in main.js del cliente):

function confirmLogin() { 
    Meteor.call('loggedIn', function (error, result) { 
     Session.set("loggedIn", result); 
    }); 

} 

Il metodo loggedin (nel server del principale.js):

loggedIn: function() { 
    var toReturn = false; 
    var userDetails = Meteor.user(); 
    if (typeof userDetails["services"] !== "undefined") { 
     if (typeof userDetails["services"]["facebook"] != "undefined") { 
      toReturn = true; 
     } 
    } 

    return toReturn; 
}, 

L'helper rilevanti:

loggedIn: function() { 
    return Session.get("loggedIn"); 
}