用简单的英语,Tracker.autorun做什么?

Yea*_*ats 27 javascript meteor

Tracker方法并不完全属于Meteor功能的核心,很少用于教程和初学者书籍(如果它们没有得到很好的解释),因此被认为比大多数人更"可怕"框架的其余部分.

举个例子,我从未设法与Tracker.autorun我的项目争吵,因为它似乎永远不会做出预期的事情.这就是文档所说的:

现在运行一个函数,并在其依赖项发生更改时重新运行它.

对我而言,这听起来像是让非反动源反动的一种方式,但是接下来你会看到这样的例子,第一个看起来像这样:

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

这与不使用Tracker.autorun有何不同?游标已经是一个反动的来源,并且让下一个例子处理更加混乱事情处理另一个反动的来源:塞申斯.

是否Tracker.autorun只与反动源工作,如果有什么是使用它们内部的利益Tracker?让他们倍加反动?

sai*_*unt 37

为了实现反应式编程(事件驱动编程的一种变体),Meteor使用了两个不同的概念:

  • 反应计算:每次修改其底层依赖项时将被反应重新运行的代码片段.
  • 反应数据源:在反应计算中使用时能够注册依赖关系的对象,使其无效并使其与新数据值一起运行.

这两个概念由两个很少使用的底层Tracker对象实现,即Tracker.Computation和辅助对象Tracker.Dependency,它是一个用于存储一组计算的容器.

A Tracker.Computation是一个有两个重要方法的对象:

  • invalidate(),这导致计算重新运行.
  • onInvalidate(callback) 用于实际运行计算任意代码.

当你调用时Tracker.autorun,你基本上是在创建一个新的计算并onInvalidate使用你传递的函数作为参数注册一个回调.

A Tracker.Dependency是具有2种方法的计算的集合.

  • depend() :将当前计算添加到集合中.
  • changed() :调用时,使每个已注册的计算无效.

当一个被动数据源在计算中注册一个依赖项时,它正在调用Dependency.depend(),它只是将当前计算(如果有的话)添加到一组被跟踪的计算中.

当被动数据源被修改时,它正在调用Dependency.changed(),这将使集合中的每个已注册计算无效.

资料来源:流星追踪器手册.

在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>
Run Code Online (Sandbox Code Playgroud)

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);
  }
});
Run Code Online (Sandbox Code Playgroud)