2012-09-01 12 views
33

Utilizzo di Meteor, sto tentando di capire quando utilizzare Meteor.methods() lato server mantenendo comunque gli aggiornamenti dell'interfaccia utente istantanea.Quando utilizzare Meteor.methods e utilizzare gli stub

Da Andrea Scala di introductory tutorial, egli sostiene che Meteor.methods() dovrebbe essere usato quando si vuole aggiornare e modificare i documenti di database:

L'idea è che si definiscono tutte le funzioni sul server che fanno roba pericolosa come modificare e aggiornare i dati, quindi lasciare che il client chiami tali funzioni e ottenga valori di ritorno come le normali funzioni. Il client non vede mai l'implementazione e non modifica personalmente i dati . Il server fa tutto il lavoro.

E seguendo questo consiglio, ho implementato questo nel mio codice:

lato server:

Meteor.methods({ 

    addMovie: function(data) { 
    var movie = Movies.insert({name: data}); 
    return movie; 
    }, 

    ... 

lato client:

Template.movies.events = ({ 

    'click #add-movie': function(e) { 

    var name = document.getElementById('movie-name').value; 
    Meteor.call('addMovie', name); 

    return false; 

    }, 

    ... 

questo funziona, ma è lento . L'interfaccia utente non si aggiorna all'istante come se fosse chiamata Movies.insert() sul lato client. Il docs indicano che, per risolvere il problema, è possibile creare stub sul lato client:

chiamare i metodi sul client definisce le funzioni stub associati metodi di server con lo stesso nome. Non è necessario definire uno stub per il metodo se non si desidera. In questo caso, le chiamate al metodo sono solo come le chiamate di procedura remota in altri sistemi e dovrai attendere per i risultati dal server.

Ma come dovrebbero apparire questi tronchi? Dovrebbe fondamentalmente sembrare uguale al metodo lato server? Se è così, qual è il punto? Sto cercando una spiegazione più completa dell'uso e dello scopo di Meteor.methods(), il punto/l'uso degli stub e la loro implementazione.

EDIT: David Greenspan ha contribuito a chiarire l'uso di Meteor.methods() e stub su meteor-talk.

+1

Sei felice con la risposta di David? Se è così, basta pubblicarlo come risposta e accettarlo. –

risposta

19

Ecco un altro esempio.

dire che stai scrivendo un gioco di bingo e fai clic sul pulsante per chiamare "casa!" .. nell'evento click puoi chiamare un metodo, ad es.

Method.call("callHouse"); 

questo invocherà il metodo di server:

// on the server 
Meteor.methods({ 
    callHouse: function() { 
    if (currentGame.isInProgress) { 
     currentGame.winner = this.userId; 
     currentGame.end(); 
    } 
    } 
}); 

se sei il primo a chiamare "casa", il metodo segneremo come il vincitore .. comunque, facciamo finta il metodo è estremamente è lento e la tua app client è in attesa .. sei sicuro al 99% che il server confermerà che sei il vincitore - vuoi solo aggiornare lo schermo dell'utente senza aspettare .. in questo caso implementa uno stub lato client:

// on the client 
Meteor.methods({ 
    callHouse: function() { 
    currentGame.winner = Meteor.userId(); 
    // add any other side-effects you expect to occur here 
    } 
}); 

quando il risultato del server ritorna, se i dati restituiti sono diversi da quelli impostati nello stub, lo correggeranno e aggiorneranno di conseguenza lo schermo.

+0

Perché hai usato 'this.userId' sul server e' Meteor.userId() 'sul client? – CaptSaltyJack

+0

non ricordo, ho scomposto Meteor anni fa – Lloyd

+4

Peccato. 1.0 rocce! – CaptSaltyJack

12

In breve:

definire alcuni metodi (Meteor.methods) nei file spinto al sever che farà il lavoro effettivo sul server, definire alcuni metodi (Meteor.methods) nei file spinti al cliente per ottenere un comportamento 'istantanea' sul client (ad esempio un indicatore di carico) fino a quando il server spinge le conseguenti modifiche al client

Ecco post originale di David:

Ciao Ben,

In linea di principio, un metodo può eseguire azioni completamente diverse sul client e sul server , ad esempio mostrando un indicatore di caricamento sul client e parlando con un'API remota sul server. Chiama a Meteora.i metodi sul client definiscono il comportamento del client e le chiamate a Meteor.methods sul server definiscono il comportamento del server.

Per i metodi che operano sul database, spesso la stessa implementazione farà per entrambi. La versione client influisce sul database lato client (la "cache" sul lato browser dei documenti sottoscritti da a) e la versione lato server influisce sul database reale. Quando il client si riavvia, "scatta" sul risultato delle mutazioni lato server; le mutazioni del database lato client sono scartate (o annullate, a seconda di come ci si pensa). Se un metodo lato client chiama altri metodi, queste chiamate secondarie sono non remotato sul server . La versione lato server chiamerà gli stessi metodi su server, o meno, come meglio ritiene opportuno.

Quindi qualsiasi implice di metodo sul lato client fornito è solo una "simulazione" e non deve essere preciso (potrebbe non essere possibile). La speranza è che in genere si ottiene la simulazione impl gratuitamente perché è la stessa del server impl!

Questo risponde alla tua domanda?

- David

+0

Grazie Jay. Avevo intenzione di scrivere una risposta successiva a questo, una volta che avevo più esperienza nel gestire gli stub. Potrei eventualmente farlo, ma accetterò la tua risposta per ora. – bento

+0

@jay, l'utilizzo di un metodo per client e server (al di fuori delle cartelle client e server) avrà gli stessi effetti? – securecurve

+2

Hi @securecurve Lo stub è pensato solo per l'aggiornamento immediato del client e il suo risultato verrà sovrascritto una volta che il server ha eseguito l'operazione e restituito. Ad esempio, se si dispone di un metodo upVote, sul proprio client, è sufficiente aggiungere 1 ai voti e aggiornare l'interfaccia utente, ma allo stesso tempo Meteor chiamerà lo stesso metodo sul server (che può o meno restituire lo stesso risultato a seconda se altre persone hanno votato per esempio) – jay

3

Se si definisce un metodo su un file condiviso da client/server come /collections non sarebbe accessibile a entrambi e automaticamente lo stub?

Quindi:

/collections/houses.js

Meteor.methods({ 
    callHouse: function() { 
    if (currentGame.isInProgress) { 
     currentGame.winner = this.userId; 
     currentGame.end(); 
    } 
    } 
}); 

Questo sarà a disposizione sia il client e server. Se non passa, il server rifiuterà automaticamente l'aggiornamento del client/lo annullerà.

+0

È sicuro? Poiché l'utente ha accesso al codice –

+0

Sì, si utilizzano le regole di sicurezza Meteor per questo. –

+0

@BrunoLemos Anch'io ho avuto questa preoccupazione all'inizio, ma parte dei principi di progettazione dietro Meteor è che è database ovunque, quindi è possibile utilizzare gli stessi metodi per accedere al database dal client e dal server. Non importa che il client abbia accesso al codice, perché indipendentemente da ciò che è sul lato client, il lato server verrà sempre convalidato. – d4nyll

3

Come detto Daniel è possibile definire un metodo su un file che non è presente nelle directory client o server e disponibile su entrambi i lati. È inoltre possibile utilizzare il valore booleano isSimulation per effettuare ulteriori controlli.Ad esempio potrebbe essere qualcosa del genere:

Meteor.methods({ 
    addMovie: function (movieData) { 
    if (!this.isSimulation) { 
     check(movieData, someAdditionaCheckinFunc); 
    } 
    Movies.insert(movieData); 
    } 
}) 

Così il codice nel ramo condizionale verrà eseguito solo sul server.