2015-05-30 1 views
25

I metodi Tracker non appartengono esattamente al nucleo della funzionalità di Meteor, sono usati raramente in tutorial e libri per principianti (e se sono così non sono spiegati molto bene), e di conseguenza sono considerati molto più "spaventosi" rispetto alla maggior parte del resto del framework.In inglese semplice, cosa fa Tracker.autorun?

Io, per esempio, non sono mai riuscito a scambiare Tracker.autorun in un mio progetto come non sembra mai fare ciò che ci si aspetta da esso. Questo è ciò che i documenti dicono che fa:

Eseguire una funzione ora ed eseguire di nuovo in un secondo momento ogni volta che le sue dipendenze cambiamento.

Per me questo suona come un modo di rendere fonti non reazionari reazionaria, ma poi si arriva agli esempi, il primo dei quali si presenta così:

Tracker.autorun(function() { 
    var oldest = _.max(Monkeys.find().fetch(), function (monkey) { 
    return monkey.age; 
    }); 
    if (oldest) 
    Session.set("oldest", oldest.name); 
}); 

Come funziona esattamente questo diverso da non usando Tracker.autorun? I cursori sono già una fonte reazionaria, e per rendere le cose più confuse il prossimo esempio si occupa di un'altra fonte reazionaria: Sessioni.

Vuol Tracker.autorun funzionano solo con le fonti reazionari, e in caso affermativo qual è il vantaggio di utilizzare al loro interno un Tracker? Rendendoli doppiamente reazionari?

risposta

33

di attuare una programmazione reattiva (una variante di programmazione event-driven), Meteor utilizza 2 concetti diversi:

  • computazioni reattivi: pezzi di codice che reattivamente rieseguire ogni volta le dipendenze sottostanti vengono modificati.
  • origini dati reattive: oggetti in grado di registrare dipendenze quando utilizzate all'interno di un calcolo reattivo, per invalidarlo e farlo funzionare nuovamente con il nuovo valore di dati.

Questi due concetti sono implementati da due raramente usato sottostante Tracker oggetti, vale a dire Tracker.Computation e l'oggetto helper Tracker.Dependency che è un contenitore per memorizzare una serie di calcoli.

Un Tracker.Computation è un oggetto di 2 importanti metodi:

  • invalidate(), che causa il calcolo per eseguire nuovamente.
  • onInvalidate(callback) per l'esecuzione effettiva del codice di calcolo arbitrario.

Quando si chiama Tracker.autorun, il gioco è fondamentalmente la creazione di un nuovo calcolo e la registrazione di un onInvalidate richiamata con la funzione si passa come argomento.

A Tracker.Dependency è una raccolta di calcoli con 2 metodi.

  • depend(): aggiunge il calcolo corrente al set.
  • changed(): quando chiamato, invalida tutti i calcoli registrati.

Quando una sorgente dati reattiva registra una dipendenza in un calcolo, si chiama Dependency.depend(), che aggiunge semplicemente il calcolo corrente (se presente) per la serie di calcoli cingolati.

Quando la sorgente di dati reattivi viene modificata, chiama Dependency.changed() che invalida tutti i calcoli registrati nel set.

Fonte: The Meteor Tracker manual.

Nel framework Meteor, di solito si tratta solo di oggetti di livello superiore che implementano i concetti di programmazione reattiva.

  • calcoli reattivi sono generati usando Tracker.autorun, da aiutanti di template predefiniti vengono sempre eseguite all'interno di un calcolo reattiva.
  • fonti di dati reattivi stanno usando Tracker.Dependency per invalidare calcoli, essi includono i cursori MiniMongo, Session variabili, Meteor.user(), ecc ...

Utilizzare Tracker.autorun quando è necessario eseguire nuovamente reattivo codice arbitrario al di fuori di aiutanti di modello, per esempio all'interno di un evento ciclo di vita onRendered, utilizzare la scelta rapida this.autorun (generazione di un calcolo reattivo che viene automaticamente interrotto quando il modello viene distrutto) per reagire a eventuali modifiche delle fonti di dati reattive.

Ecco un piccolo esempio di un modello che conta quante volte hai fatto clic su un pulsante e reimposta il contatore su 0 quando si fa clic su 10 volte.

HTML

<template name="counter"> 
    <div class="counter> 
    <button type="button">Click me !</button> 
    <p>You clicked the button {{count}} times.</p> 
    </div> 
</template> 

JS

Template.counter.onCreated(function(){ 
    this.count = new ReactiveVar(0); 
}); 

Template.counter.onRendered(function(){ 
    this.autorun(function(){ 
    var count = this.count.get(); 
    if(count == 10){ 
     this.count.set(0); 
    } 
    }.bind(this)); 
}); 

Template.counter.helpers({ 
    count: function(){ 
    return Template.instance().count.get(); 
    } 
}); 

Template.counter.events({ 
    "click button": function(event, template){ 
    var count = template.count.get(); 
    template.count.set(count + 1); 
    } 
}); 
+0

Grande risposta, si risolve un altro problema che stavo avendo dove nel onRendered, nel Tracker.autorun, non ho potuto ottenere l'accesso al modello utilizzando this.find ('...'). Usando this.autorun e.bind (questo) sono riuscito a far funzionare le cose. Domanda, è il .bind (questo) necessario per fare un this.find ('')? E qual è lo scopo di questo? – Aaron

+1

Beh, questa sarebbe un'altra domanda nel suo insieme, date un'occhiata a: http://javascriptissexy.com/javascript-apply-call-and-bind-methods-are-essential-for-javascript-professionals/ Meteor 1.2 sarà introdurre il supporto ES2015 e le funzioni Arrow, rendendo questo uso specifico del binding irrilevante. https://github.com/lukehoban/es6features#arrows – saimeunt