Ответ 1
Чтобы реализовать реактивное программирование (вариант программирования, управляемого событиями), Meteor использует две различные концепции:
- реактивные вычисления: фрагменты кода, которые будут повторно перезапускаться каждый раз при изменении их зависимостей.
- источники реактивных данных: объекты, способные регистрировать зависимости, когда они используются внутри реактивного вычисления, чтобы сделать его недействительным и заставить его снова запустить с новым значением данных.
Эти два понятия реализуются двумя редко используемыми базовыми объектами Tracker
, а именно Tracker.Comput и вспомогательным объектом Tracker.Dependency, который является контейнером для хранения набора вычислений.
A Tracker.Computation
- объект с двумя важными методами:
-
invalidate()
, что вызывает повторное вычисление. -
onInvalidate(callback)
для фактического запуска произвольного кода вычисления.
Когда вы вызываете Tracker.autorun
, вы в основном создаете новое вычисление и регистрируете обратный вызов onInvalidate
с передачей функции в качестве аргумента.
A Tracker.Dependency
представляет собой набор вычислений с двумя методами.
-
depend()
: добавляет текущее вычисление к набору. -
changed()
: при вызове аннулирует все зарегистрированные вычисления.
Когда реактивный источник данных регистрирует зависимость внутри вычисления, он вызывает Dependency.depend()
, который просто добавляет текущее вычисление (если оно есть) к набору отслеживаемых вычислений.
Когда изменяется источник реактивной информации, он вызывает Dependency.changed()
, который будет лишать законных результатов всех зарегистрированных вычислений в наборе.
Источник: Руководство по отслеживанию Meteor Tracker.
В структуре Meteor вы обычно имеете дело только с несколькими объектами более высокого уровня, реализующими концепции реактивного программирования.
- реактивные вычисления порождаются с помощью
Tracker.autorun
, по умолчанию шаблонные помощники всегда запускаются внутри реактивного вычисления. - источники реактивных данных используют
Tracker.Dependency
для недействительности вычислений, к ним относятся курсоры MiniMongo, переменныеSession
,Meteor.user()
и т.д.
Используйте Tracker.autorun
, когда вам необходимо повторно перезапустить произвольный код вне помощников шаблонов, например внутри события шаблона onRendered
lifecycle, используйте ярлык this.autorun
(создайте реактивное вычисление, которое автоматически остановится, когда шаблон уничтожены), чтобы реагировать на любые изменения реактивных источников данных.
Вот небольшой пример шаблона, который подсчитывает, сколько раз вы нажимали кнопку и reset счетчик на 0 при нажатии 10 раз.
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);
}
});