The Tracker methods don\'t exactly belong to the core of Meteor\'s functionality, are seldomly used in tutorials and beginner books (and if they are they are not explained very
To implement reactive programming (a variant of event driven programming), Meteor uses 2 different concepts :
These two concepts are implemented by two rarely used underlying Tracker
objects, namely Tracker.Computation and the helper object Tracker.Dependency which is a container for storing a set of computations.
A Tracker.Computation
is an object with 2 important methods :
invalidate()
, which is causing the computation to rerun.onInvalidate(callback)
for actually running the computation arbitrary code.When you call Tracker.autorun
, you're basically creating a new computation and registering an onInvalidate
callback with the function you pass as argument.
A Tracker.Dependency
is a collection of computations with 2 methods.
depend()
: adds the current computation to the set.changed()
: when called, invalidates every registered computations.When a reactive data source registers a dependency inside a computation, it is calling Dependency.depend()
, which simply adds the current computation (if any) to the set of tracked computations.
When the reactive data source is modified, it is calling Dependency.changed()
which is going to invalidate every registered computations in the set.
Source : The Meteor Tracker manual.
In the Meteor framework, you usually only deal with several higher level objects implementing the concepts of reactive programming.
Tracker.autorun
, by default template helpers are always run inside a reactive computation.Tracker.Dependency
to invalidate computations, they include MiniMongo cursors, Session
variables, Meteor.user()
, etc...Use Tracker.autorun
when you need to reactively rerun arbitrary code outside of template helpers, for example inside a template onRendered
lifecycle event, use the shortcut this.autorun
(spawning a reactive computation that is automatically stopped when the template is destroyed) to react to any reactive data sources modifications.
Here is a small example of a template that counts how many times you clicked a button and reset the counter to 0 when clicked 10 times.
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);
}
});