1

I have two separate template and in both template(rendered) i am doing $(window).scroll() but however go to one template another, the $(window).scroll() is running from both, previous as well as current template.

Code Snippets as below:

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

Console:

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

But if i refresh the browser, then it is coming from current template only.

Why this is happening any idea? what is the way to fix this.

iamhimadri
  • 532
  • 1
  • 5
  • 20

2 Answers2

7

Destroying a template in Meteor will perform internal cleanup regarding the template rendering engine (Blaze) and it will unregister events declared via template event maps, but it won't unregister global window events Meteor is not aware of.

After registering a custom global event in the onRendered lifecycle event callback using $.on, you'll need to unregister it in the onDestroyed callback using $.off.

You can use this pattern to register and unregister handlers :

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

By attaching a this-bound function as a property of the template instance, you can perform template instance specific logic inside the event handler.

saimeunt
  • 22,666
  • 2
  • 56
  • 61
  • cheers!! got it and it works fine. i have one more query to you...which one is better **$(window).off('scroll')** or **$(window).unbind('scroll')** ?? – iamhimadri Jul 02 '15 at 13:31
  • Use `$.on` and `$.off`, `$.bind` and `$.unbind` are deprecated and may be removed in future versions of jQuery. – saimeunt Jul 02 '15 at 14:00
1

you need to remove your listener manually when template is destroyed.

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');
}
pahan
  • 2,445
  • 1
  • 28
  • 36