即使模板在流星中被销毁,$(window).scroll(...)也在运行

时间:2015-07-02 11:33:15

标签: javascript jquery templates meteor meteorite

我有两个单独的模板,在两个模板中(渲染)我正在做 $(窗口).scroll(),但是另一个模板是 $(窗口)。 scroll()从前一个模板和当前模板运行。

代码片段如下:

dashboard1.js

Template.dashboard1.rendered = function(){
    $(window).scroll(function() {
        console.log('dashboard1 scroll');
        //... doing pagination and sticky element for dashboard1
    });
}

Template.dashboard1.destroyed = function(){
    console.log('dashboard1 destroyed');
}

dashboard2.js

Template.dashboard2.rendered = function(){
    $(window).scroll(function() {
        console.log('dashboard2 scroll');
        //... doing pagination and sticky element for dashboard2
    });
}

Template.dashboard2.destroyed = function(){
    console.log('dashboard2 destroyed');
}

控制台:

dashboard1 destroyed
dashboard2 scroll
dashboard1 scroll
dashboard2 scroll
dashboard1 scroll
dashboard2 scroll

但是如果我刷新浏览器,那么它只来自当前模板。

为什么会发生这种想法?解决这个问题的方法是什么?

2 个答案:

答案 0 :(得分:7)

销毁Meteor中的模板将执行有关模板渲染引擎(Blaze)的内部清理,它将取消注册通过模板事件映射声明的事件,但它不会取消注册Meteor不知道的全局窗口事件的。

使用onRendered$.on生命周期事件回调中注册自定义全局事件后,您需要使用onDestroyed$.off回调中取消注册。

您可以使用此模式注册和取消注册处理程序:

Template.dashboard1.onRendered(function(){
  this.scrollHandler = function(){
    // you can use the this keyword here to reference the template instance
    console.log("dashboard1 scroll");
    //... doing pagination and sticky element for dashboard1
  }.bind(this);
  $(window).on("scroll" ,this.scrollHandler);
});

Template.dashboard1.onDestroyed(function(){
  $(window).off("scroll", this.scrollHandler);
  console.log("dashboard1 destroyed");
});

通过将此绑定函数作为模板实例的属性附加,您可以在事件处理程序中执行特定于模板实例的逻辑。

答案 1 :(得分:1)

您需要在销毁模板时手动删除侦听器。

var scrollHandler = function() {
  console.log('dashboard1 scroll');
}

Template.dashboard1.rendered = function() {
  $(window).scroll(scrollHandler);
}

Template.dashboard1.destroyed = function() {
  $(window).off("scroll", scrollHandler);
  console.log('dashboard1 destroyed');
}