5

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?

3
  • 2
    Did you try to consider using a directive to add the scroll listener (and function) to the component you want to react to the scroll ? Generally using $document in a controller is not a good practice. Commented May 28, 2015 at 15:28
  • @Okazari You are right. the directive is the right way but i am beginner in angular and i am not prfessional in directive :D Commented May 28, 2015 at 15:57
  • 1
    I'm not sure i could do this myself, i'm just giving some clues. A lot of custom directives are not done in the right way or simply done for a bad usecase. Till your usecase would be a good one for a directive i'd just point this out :) Commented May 28, 2015 at 16:01

3 Answers 3

5

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.

Sign up to request clarification or add additional context in comments.

3 Comments

@ali - You have to do this in each of the 100 controllers you mentioned. Take a look at my solution
Not at all, you have to do it only in the same controller where you bind it (and it makes sense to bind and unbind in the same location in the code, making it as loosely coupled as possible)
@ShankarSangoli no. i test above solution and it work correctly. your answer seems another good idea too.
3

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

Comments

2

You can listen to $route change event and bind/unbind the event based on the controller.

angular.module('myApp')
.run(function ($rootScope, $document) {
    $rootScope.$on('$routeChangeStart', function(next, current) { 
       //Look for the appropriate controller here using next.controller object
       //and bind/unbind the events   
     });
});

$route documentation here https://code.angularjs.org/1.0.8/docs/api/ng.$route

This logic is only at one place so you don't have to worry about any controller to maintain to bind/unbind logic.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.