【问题标题】:In plain English, what does Tracker.autorun do?用简单的英语来说,Tracker.autorun 是做什么的?
【发布时间】:2015-08-13 07:38:06
【问题描述】:

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);
});

这与不使用Tracker.autorun 有什么不同?游标已经是一个反动源,为了让事情更加混乱下一个示例处理另一个反动源:Sessions。

Tracker.autorun 是否仅适用于反动源,如果是这样,在Tracker 中使用它们有什么好处?让他们加倍反动?

【问题讨论】:

    标签: javascript meteor


    【解决方案1】:

    为了实现反应式编程(事件驱动编程的一种变体),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);
      }
    });
    

    【讨论】:

    • 很好的答案,它解决了我在 onRendered 中遇到的另一个问题,在 Tracker.autorun 中,我无法使用 this.find('...') 访问模板。通过使用 this.autorun 和.bind(this) 我能够让事情正常工作。问题,.bind(this) 是否需要执行 this.find('')?它的目的是什么?
    • 好吧,这将是另一个问题,看看:javascriptissexy.com/… Meteor 1.2 将引入 ES2015 支持和箭头函数,使得这种特定的绑定使用无关紧要。 github.com/lukehoban/es6features#arrows
    • 我认为自动运行应该始终在 onCreated 中。我认为将其放入 onRendered 可能会复制跟踪器。 this.count 也无法从跟踪器功能访问。通过 Template.instance().count 访问它。
    猜你喜欢
    • 2011-02-01
    • 2011-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多