为了实现反应式编程(事件驱动编程的一种变体),Meteor 使用了 2 个不同的概念:
- 反应式计算:每次修改其基础依赖项时都会反应式重新运行的代码片段。
- 反应式数据源:在反应式计算中使用时能够注册依赖关系的对象,以使其无效并使用新数据值再次运行。
这两个概念由两个很少使用的底层Tracker 对象实现,即Tracker.Computation 和辅助对象Tracker.Dependency,它是一个用于存储一组计算的容器。
Tracker.Computation 是一个具有 2 个重要方法的对象:
-
invalidate(),这导致计算重新运行。
-
onInvalidate(callback) 用于实际运行计算任意代码。
当您调用Tracker.autorun 时,您基本上是在创建一个新的计算并使用您作为参数传递的函数注册一个onInvalidate 回调。
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(生成一个响应式计算,该计算会在模板运行时自动停止)销毁)以对任何响应式数据源的修改做出反应。
这是一个模板的小示例,它计算您单击按钮的次数,并在单击 10 次时将计数器重置为 0。
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);
}
});