I have a controller that injects $document
to catch keydown
event.
But this event is always one keypress late.
I have another method by using $broadcast
from ng-keydown
in <body>
that works fine.
My question is : what is wrong with $document.on('keydown', ...)
?
Here is a working example :
<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>
that you can test here http://plnkr.co/edit/omhTiLi31BnEwrSwk75A
If you did this, which you shouldn't, it wouldn't be "one late" as you say:
$document.on('keydown',function(evt) {
$scope.keycode = evt.which;
$scope.$apply();
});
In Angular you shouldn't be doing these kind of operations from a controler, but from a directive, DOM manipulation and DOM events belong to the directives, concretely to the link
function of the directive.
What happens when you register an event like that is that you are registering the event inside the controller, but when the event get's triggered angular doesn't know anything about that function, so you would have to call $apply
in order to trigger the $diggest
cycle that will re-evaluate and refresh the expressions of your view.