模板被销毁时正确停止autorun()函数

时间:2014-06-19 22:57:04

标签: meteor

我有一个包含图表的模板,使用MorrisJS渲染。当currentData会话变量发生变化时,图表应该会更新,因此我将其作为一个反应性数据源:

Template.chart.rendered = function() {

    var template = this;

    Deps.autorun(function(c) {

        // Stop if the template is removed from the dom
        // Q: Is this really right?
        if(template.__component__.dom.parentNode() === null) {
            c.stop();
            return;
        }

        var results = Session.get('currentData');

        // ... render a chart with `results` as the data

        Morris.Bar({element: template.$(".chart-container"), data: results, ...});

    });

};

请注意我如何检查何时停止上面的自动运行。这是必要的,因为没有这个,当我使用模板(我使用iron-router)离开页面到另一个页面并返回时,我会在日志中收到警告,例如“无法选择删除的DomRange” 。我很确定这种情况正在发生,因为模板实例已被删除,但自动运行仍在运行。

但是,我觉得我在这里做错了。是否有(a)更好的地方放置自动运行以便它没有这个问题或(b)在从DOM中删除模板实例时停止计算的更好方法?

我试图找到一种方法来处理createddestroyed处理程序,但我无法弄清楚如何。

2 个答案:

答案 0 :(得分:6)

Tracker.autorun返回一个句柄,您可以将其存储为模板实例属性,然后在stop生命周期事件中调用其onDestroyed方法。

Template.chart.onRendered(function(){
  this.computation = Tracker.autorun(function(){...});
});

Template.chart.onDestroyed(function(){
  this.computation.stop();
});

编辑29-09-2014

在较新版本的Meteor(0.9以后版本)中,模板实例上有一个新的autorun函数可以提供更简单的代码来实现相同的结果:无需手动存储和停止计算,这是需要的由框架照顾。

Template.chart.onRendered(function(){
  this.autorun(function(){...});
});

答案 1 :(得分:1)

使用新的自动运行

Template.chart.onRendered(function(){
  this.autorun(function(computation){
    ...
    computation.stop();
  });
});

但是使用此自动运行功能,当从DOM中删除图表模板时,它会自动删除。 这是在Meteor文档here

  

模板销毁时会自动停止计算。