2014-11-13 11 views
7
Tweets = new Meteor.Collection('tweets'); 

if (Meteor.isClient) { 

    Meteor.subscribe('tweets'); 

    Template.Panel.helpers({ 
    items: function() { 
     var days_tweets = Tweets.find(); 
     console.log(days_tweets.count()); 
     return days_tweets; 
    }); 
    } 

if (Meteor.isServer) { 
    Meteor.publish('tweets', function() { 
    return Tweets.find({}, {limit: 1000}); 
    }); 

Il modello:Meteor aiutante chiamato più volte per singolo modello variabile

<body> 
<h1>This is a list of tweets</h1> 
    {{> Panel}} 
</body> 

<template name="Panel"> 
<h2>A list of tweets sorted by size</h2> 
    {{#each items}} 
     <p>item</p> 
    {{/each}} 
</template> 

E l'uscita della console al caricamento della pagina:

Tweet count: 0 
Tweet count: 129 
Tweet count: 272 
Tweet count: 366 
Tweet count: 457 
Tweet count: 547 
Tweet count: 672 
Tweet count: 814 
Tweet count: 941 
Tweet count: 1000 

Quindi la funzione di supporto spara 10 volte a pagina carico (il numero di volte varia). Qualcuno potrebbe spiegare cosa sta succedendo qui? Non riesco a trovare alcun riferimento a questo, accetta in situazioni in cui l'helper è chiamato da più {{}} sul modello. Anche un modo per fermarlo? Alla fine ho bisogno di elaborare i tweets in un colpo solo prima che vengano renderizzati.

risposta

7

Quando si trova una meteora, registra una dipendenza per l'helper del modello nella raccolta su cui è stata eseguita la ricerca. A causa di questa dipendenza, meteor chiamerà l'helper del template per ogni modifica alla collezione.

Se non si è ancora abbonati non ci sono dati caricati nella copia lato client della propria collezione mongo. Solo quando si chiama subscribe, meteor inizierà a prelevare i dati dal server.

Quindi il metodo viene chiamato più volte poiché l'abbonamento continua a inserire nuovi documenti nella copia locale della raccolta mongo, attivando nuove chiamate all'helper dei modelli.

Il miglior modello per contrastare eventuali problemi che ciò può dare è iscriversi nell'help e utilizzare il metodo ready sull'abbonato documentation. Ready è anche reattivo, quindi quando tutti i dati sono pronti, verrà cambiato in true e l'helper verrà richiamato di nuovo.

Template.Panel.helpers({ 
     items: function() { 
      var ready = Meteor.subscribe('tweets').ready(); 
      var days_tweets = Tweets.find(); 

      return { 
       data: days_tweets, 
       ready: ready 
      }; 
     }); 
    } 

modello stesso:

{{#with items}} 
    {{#if ready}} 
     {{#each data}} 
      <p>item</p> 
     {{/each}} 
    {{else}} 
     Show a spinner or whatever 
    {{/if}} 
{{/with}} 
+0

Ok grazie. Ho assunto qualcosa di simile. C'è un modo per impedirlo? (supponendo che la raccolta sul server non stia cambiando, come nel caso qui). Sembra strano avere una sincronizzazione tra il server fisso e la raccolta del client in esecuzione in modo asincrono. – kendlete

+0

@kendlete ha aggiornato la mia risposta con un esempio su come lavorare con il comportamento del sistema di sottoscrizione di mete –

+0

'Meteor.subscribe()' ha anche un callback già presente nei documenti, che potrebbe essere utilizzato per ritardare l'inserimento di più codice finché l'abbonamento non è pronto. È diverso da .ready() che restituisce un valore booleano se l'abbonamento è pronto. Un po 'più ingombrante, forse, dell'approccio di Marco. – Paul

Problemi correlati