我有一个控制器,它注入$document
以捕获keydown
事件。但这个事件总是晚一个按键。
我有另一种方法,在<body>
中使用ng-keydown
中的$broadcast
,效果很好。
我的问题是:$document.on('keydown', ...)
出了什么问题?
下面是一个工作示例:
<body ng-app="app" ng-keydown="$broadcast('mykeydown', $event);">
<div ng-controller="BroadcastController">
key down by broadcast: {{keycode}}
</div>
<div ng-controller="KeyFromDocController">
key down from $document : {{keycode}} <br>[always one late !!!]
</div>
</body>
<script>
angular.module('app', [])
.controller('BroadcastController', function($scope) {
$scope.keycode = '?';
$scope.$on('mykeydown',function(msg,evt) {
$scope.keycode = evt.which;
});
})
.controller('KeyFromDocController', function($scope,$document) {
$scope.keycode = '?';
$document.on('keydown',function(evt) {
$scope.keycode = evt.which;
});
});
</script>
你可以在这里测试http://plnkr.co/edit/omhTiLi31BnEwrSwk75A
如果你这样做了,你不应该这样做,就不会像你说的那样"迟到一次":
$document.on('keydown',function(evt) {
$scope.keycode = evt.which;
$scope.$apply();
});
示例
在Angular中,您不应该从控制器执行此类操作,而是从指令执行此类操作。DOM操作和DOM事件属于指令,具体而言属于指令的link
函数。
当您注册这样的事件时,会发生的情况是,您正在控制器内注册该事件,但当事件get被触发时,angular对该函数一无所知,因此您必须调用$apply
才能触发$diggest
循环,该循环将重新评估和刷新视图的表达式。