web-dev-qa-db-fra.com

La directive AngularJS ng-keydown ne fonctionne que pour le contexte <input>?

AngularJS est relativement nouveau mais je l’ai trouvé jusqu’à présent à mon goût. Pour mon projet actuel, j'ai besoin de la fonctionnalité de raccourci clavier et je suis heureux de constater qu'elle est prise en charge depuis la version 1.1.2.

La directive ng-keydown ( http://code.angularjs.org/1.1.3/docs/api/ng.directive:ngKeydown ) fonctionne comme prévu pour les types d'entrée, mais ne me permet pas d'entrer dans un autre contexte comme div, etc. ce qui semble étrange étant donné que la documentation dit le contraire.

Voici un exemple minimal ( http://jsfiddle.net/TdXWW/12/ ) du fonctionnement ou du non-fonctionnement:

<input ng-keydown="keypress($event)">
<div ng-keydown="keypress($event)">

REMARQUE: Je sais que cela pourrait être traité simplement avec jQuery ( http://www.mkyong.com/jquery/how-to-check-if-an-enter-key-is-pressed-with-jquery/ ) mais je préfère de loin comprendre comment traiter cela dans AngularJS.

36
Lukas N.P. Egger

J'avais le même problème et j'ai pu le résoudre en suivant cette astuce simple fournie dans ce commentaire: https://stackoverflow.com/a/1718035/80264

Vous devez donner à la div un tabindex afin qu’elle puisse recevoir le focus.

<div id="testdiv" tabindex="0"></div>
82
João Josézinho

Merci! Pour conclure, j'ai travaillé en injectant $ document dans ma directive puis:

MyApp.directive('myDirective', function($document) {
return {
...
 $document.keydown(function(e){
   console.log(e)
 })
}
9
Finn Johnsen

C’est ainsi que j’ai fonctionné à la fin.

Ajoutez ng-app à l'élément html et ng-keyup et ng-keydown à l'élément body:

<html ng-app="myApp" ng-controller="MainCtrl">
.....
<body ng-keydown="keyPress($event);" ng-keyup="keyRelease($event);">

Ensuite, les fonctions de mon contrôleur traitent avec l'événement appelant event.which pour obtenir le code de clé (dans mon implémentation, je mets une var sur rootScope mais vous pouvez aussi diffuser vers d'autres contrôleurs)

$scope.keyPress = function(eve) {
    if (eve.which === 16) { // shift
        // $rootScope.$broadcast('doShift');
        $rootScope.shiftOn = true;
    };
};
8
Gurnard

Le commentaire de charlietfl a clarifié les choses et lié l'événement à $ (document) a fonctionné comme prévu! Message à retenir: La documentation d’AngularJS n’est pas vraiment exhaustive, c’est-à-dire qu’elle nécessite des connaissances de base.

1
Lukas N.P. Egger
angular.module('app').directive('executeOnEnter', function () {
    return {
        restrict: 'A',
        link: function (scope, el, attrs, $rootScope) {                      
            $('body').on('keypress', function (evt) {
                if (evt.keyCode === 13) {
                    el.trigger('click', function () {
                    });
                }            
            })

        },
        controller: function ($rootScope) {
            function removeEvent() {
                $("body").unbind("keypress");
            }
            $rootScope.$on('$stateChangeStart', removeEvent);
        }
    }
})
0
vvn050