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

Javascript AngularJS:将滚动事件绑定到一个控制器而不是所有控制器,javascript,angularjs,scroll,dom-events,Javascript,Angularjs,Scroll,Dom Events,假设我有100个控制器,我需要将一个事件绑定到其中一个 当控制器启动时,滚动事件侦听器将连接到文档并正常工作。但当控制器更改时,滚动事件仍然存在&导致其他控制器出现问题 我找到的唯一解决方案是在所有其他99个控制器中取消绑定scroll事件,但这很愚蠢 angular.module('test', ['ngRoute']) .config(function($routeProvider){ $routeProvider .when('/c1', {controller:'

假设我有100个控制器,我需要将一个
事件绑定到其中一个

当控制器启动时,滚动事件侦听器将连接到文档并正常工作。但当控制器更改时,滚动事件仍然存在&导致其他控制器出现问题

我找到的唯一解决方案是在所有其他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'); 
  });
})
有人在读关于它的书

2016年更新

如果您现在正在使用组件(您应该这样做),那么这个方法可以很容易很好地更新。只需利用新的语法,掌握为这些情况提供的生命周期

因此,在
$onInit()
中绑定,在
$ondestory中解除绑定:

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

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

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

有关生命周期挂钩的更多信息。

您可以收听
$route
更改事件并基于控制器绑定/解除绑定事件

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   
     });
});
controller('c1', function($scope, $document){
    ...
    $document.bind('scroll', function(){...});
    $scope.$on('$destroy', function () {
        $document.unbind('scroll');        
    }
    ...
})
$route
此处为文档。$route


此逻辑仅在一个位置,因此您不必担心任何控制器要维护绑定/解除绑定逻辑。

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

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   
     });
});
controller('c1', function($scope, $document){
    ...
    $document.bind('scroll', function(){...});
    $scope.$on('$destroy', function () {
        $document.unbind('scroll');        
    }
    ...
})

您是否尝试使用指令来将滚动侦听器(和函数)添加到要对滚动进行响应的组件?通常在控制器中使用$document不是一个好的做法。@Okazari您说得对。
指令
是正确的方法,但我在角度方面是初学者,在指令方面我不专业:我不确定我自己能做到这一点,我只是给出一些线索。许多自定义指令没有以正确的方式执行,或者只是针对一个糟糕的用例执行。在您的用例成为指令的好用例之前,我只想指出:)@ali-您必须在您提到的100个控制器中的每一个中执行此操作。看看我的解决方案一点也不,你只需要在绑定它的同一个控制器中执行它(在代码中的同一位置绑定和解除绑定是有意义的,使其尽可能松散耦合)@Shankarsangli no.我测试了上述解决方案,它工作正常。你的回答似乎也是个好主意。