2015-05-30 2 views
25

Методы Tracker точно не относятся к ядру функциональности Meteor, редко используются в учебниках и книгах-новичках (и если они не очень хорошо объясняются), и, как следствие, они считаются намного более «страшными», чем большая часть остальной части структуры.На простом английском языке, что делает Tracker.autorun?

Я, например, никогда не мог спорить с Tracker.autorun в мой проект, поскольку он никогда не делает того, чего от него ожидают. Это то, что говорят документы:

Запустите функцию сейчас и запустите ее позже, когда будут установлены ее зависимости .

Для меня это звучит как способ сделать не-реакционные источники реакционным, но тогда вы пришли в примерах, первый из которых выглядит следующим образом:

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

Как именно это отличается от не используя Tracker.autorun? Курсоры уже являются реакционным источником, и для того, чтобы сделать вещи более запутанными , следующий пример касается другого реакционного источника: Сессии.

Работает ли Tracker.autorun только с реакционными источниками, и если да, то в чем польза от использования их внутри Tracker? Сделать их вдвойне реакционными?

ответ

33

Для реализации реактивного программирования (варианта управляемых событий программирования), Метеор использует 2 различные концепции:

  • реакционноспособных вычисления: куски кода, которые будут реактивно повторно запускать каждый раз, лежащие в их основе зависимостей модифицированные.
  • реактивные источники данных: объекты, способные регистрировать зависимости при использовании внутри реактивного вычисления, чтобы аннулировать его и снова запустить с новым значением данных.

Эти две концепции реализованы с помощью двух редко используется, лежащий в основе Tracker объектов, а именно Tracker.Computation и вспомогательный объект Tracker.Dependency, который представляет собой контейнер для хранения набора вычислений.

Tracker.Computation представляет собой объект с 2-мя важными методами:

  • invalidate(), которая вызывает вычисление перезапускать.
  • onInvalidate(callback) для фактического запуска вычислительного произвольного кода.

Когда вы звоните Tracker.autorun, вы в основном создания нового вычисления и регистрации в onInvalidate обратного вызова с помощью функции вы передаете в качестве аргумента.

A Tracker.Dependency представляет собой набор вычислений с 2 ​​методами.

  • depend(): добавляет текущее вычисление к набору.
  • changed(): при вызове аннулируются все зарегистрированные расчеты.

Когда реактивная источник данных регистрирует зависимость внутри вычислений, он звонит Dependency.depend(), который просто добавляет текущее вычисление (если таковые имеются) к набору отслеживаемых вычислений.

Когда изменяется реактивный источник данных, он вызывает Dependency.changed(), что приведет к аннулированию всех зарегистрированных вычислений в наборе.

Источник: The Meteor Tracker manual.

В рамках Meteor вы обычно имеете дело только с несколькими объектами более высокого уровня, реализующими концепции реактивного программирования.

  • реактивные вычисления порождаются с использованием Tracker.autorun, по умолчанию шаблонные помощники всегда запускаются внутри реактивного вычисления.
  • реактивные источники данных используют Tracker.Dependency недействительное вычисление, они включают в себя MiniMongo курсоры, Session переменных, Meteor.user() и т.д ...

Используйте Tracker.autorun, когда вам нужно реактивно перезапускать произвольный код вне шаблонов хелперов, например внутри шаблона onRendered событие жизненного цикла, используйте ярлык this.autorun (создавая реактивное вычисление, которое автоматически останавливается при уничтожении шаблона), чтобы реагировать на любые изменения источников реактивных данных.

Вот небольшой пример шаблона, который подсчитывает, сколько раз вы нажали кнопку и сбросили счетчик на 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); 
    } 
}); 
+0

Великий ответ, это решить еще один вопрос у меня был где в onRendered, в Tracker.autorun, я не мог получить доступ к шаблону, используя this.find ('...'). Используя this.autorun and.bind (это), я смог заставить все работать. Вопрос: является ли .bind (this) необходимым сделать this.find ('')? И в чем его цель? – Aaron

+1

Ну, это был бы еще один вопрос в целом, посмотрите на: http://javascriptissexy.com/javascript-apply-call-and-bind-methods-are-essential-for-javascript-professionals/. Meteor 1.2 будет внедрить поддержку ES2015 и функции Arrow, что делает это конкретное использование привязки несущественным. https://github.com/lukehoban/es6features#arrows – saimeunt

Смежные вопросы