Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS: bind scroll event to one controller not all

Consider I have 100 controllers and I need to bind a scroll event to one of them.

When the controller fired, the scroll event listener attached to document and work correctly. but when the controller change, the scroll event remain & cause problem in other controller!

The only solution I find is that unbind the scroll event in all of other 99 controllers but it is stupid!

angular.module('test', ['ngRoute'])
.config(function($routeProvider){
    $routeProvider
        .when('/c1', {controller:'c1', templateUrl:'/c1.html'})
        .when('/c2', {controller:'c2', templateUrl:'/c2.html'})
        ...
        .when('/c100', {controller:'c100', templateUrl:'/c100.html'})
        .otherwise({redirectTo: '/c1'});
})
.controller('c1', function($document){
    ...
    $document.bind('scroll', function(){...});
    ...
})
.controller('c2', function($document){
    $document.unbind('scroll');
    ...
})
...
.controller('c100', function($document){
    $document.unbind('scroll');
    ...
})

What is the right way?

like image 480
علیرضا Avatar asked May 28 '15 15:05

علیرضا


2 Answers

You can unbind it when the scope of that controller is destroyed like so:

.controller('c1', function($document, $scope){
  $document.bind('scroll', function(){...});
  // .....
  $scope.$on('$destroy', function() {
    $document.unbind('scroll'); 
  });
})

Some reading about it here.

2016 UPDATE

If you are now using components (and you should), this method can be updated easily and nicely. Just leverage the new syntax and get hold of the lifecycle hooks Angular provides exactly for these situations.

So, bind in your $onInit(), unbind in your $onDestroy:

class SomeComponentName {
   constructor($document) {
      this.$document = $document;
   }

   $onInit() {
      this.$document.bind('scroll', evt => {});
   }

   $onDestroy() {
      this.$document.unbind('scroll');
   }
}

More on lifecycle hooks here.

like image 79
Aurelio Avatar answered Nov 07 '22 08:11

Aurelio


You have to add listener on "$destroy" event into your "c1" controller.

controller('c1', function($scope, $document){
    ...
    $document.bind('scroll', function(){...});
    $scope.$on('$destroy', function () {
        $document.unbind('scroll');        
    }
    ...
})
like image 29
jirikuchta Avatar answered Nov 07 '22 08:11

jirikuchta