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');
}
...
})
假设我有 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');
}
...
})