AngularJS: 将滚动事件绑定到一个控制器而不是所有

AngularJS: bind scroll event to one controller not all

假设我有 100 个控制器,我需要 bind 向其中一个发送 scroll 事件。

当控制器触发时,附加到文档的滚动事件侦听器可以正常工作。但是当控制器改变时,滚动事件仍然存在并导致其他控制器出现问题!

我找到的唯一解决方案是 unbind 所有其他 99 个控制器中的 scroll 事件,但它很愚蠢!

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

正确的方法是什么?

当那个控制器的作用域被销毁时,你可以解除绑定:

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

一些关于它的阅读 here

2016 年更新

如果您现在正在使用组件(并且您应该),则可以轻松且很好地更新此方法。只需利用新语法并掌握生命周期挂钩 Angular 正是为这些情况提供的。

因此,在您的 $onInit() 中绑定,在您的 $onDestroy 中解除绑定:

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

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

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

更多关于生命周期钩子的信息here

可以监听$route变化事件和bind/unbind基于控制器的事件。

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 文档在这里 https://code.angularjs.org/1.0.8/docs/api/ng.$route

这个逻辑只在一个地方,所以你不必担心任何控制器维护 bind/unbind 逻辑。

您必须将“$destroy”事件的侦听器添加到您的 "c1" 控制器中。

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