J'essaie de faire en sorte que mon contrôleur surveille une combinaison de touches. Par exemple, disons: haut en bas en bas gauche gauche gauche droite b a. Comment puis-je obtenir une détection angulaire quel que soit l'emplacement de la page actuellement affichée par l'utilisateur?
On dirait que vous pouvez utiliser ng-keydown pour le faire.
Voici un plunker de travail .
Pour cet exemple, je viens de lier ng-keydown
à <body>
. Fonctionne assez bien pour capturer tous les événements de clavier globalement.
Comme @charlietfl le fait remarquer, ng-keydown
enregistre de nombreux événements de clavier afin de rendre cette opération utilisable représenterait beaucoup de travail. Par exemple, si vous essayez d'écouter une combinaison (telle que ctrl
+ r
), la clé ctrl
sera enregistrée à plusieurs reprises.
JS:
var myApp = angular.module('myApp', []);
myApp.controller('Ctrl', function($scope) {
$scope.keyBuffer = [];
function arrays_equal(a,b) { return !(a<b || b<a); }
$scope.down = function(e) {
$scope.keyBuffer.Push(e.keyCode);
var upUp = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65];
if (arrays_equal(upUp, $scope.keyBuffer)) {
alert('thats it!');
}
};
});
HTML:
<body ng-controller="Ctrl" ng-keydown="down($event)">
J'utilise une manière différente de le faire.
$scope.keyboard = {
buffer: [],
detectCombination: function() {
var codes = {};
this.buffer.forEach(function(code) {
codes['key_' + code] = 1;
});
if ((codes.key_91 || codes.key_93) && codes.key_8) {
// I'm looking for 'command + delete'
}
},
keydown: function($event) {
this.buffer.Push($event.keyCode);
this.detectCombination();
},
keyup: function($event, week) {
this.buffer = [];
}
};
Détection des touches Retour arrière (Mac) et Suppr (PC):
<body ng-controller="Ctrl" ng-keydown="keyDown($event)">..<body>
$scope.keyDown = function(value){
if(value.keyCode == 46 || value.keyCode == 8) {
//alert('Delete Key Pressed');
}
};
Ceci n’a pas été testé, mais vous pouvez utiliser ng-keypress
<body ng-keypress="logKeys($rootScope,$event)">...</body>
Pour appeler une fonction quelque chose comme:
appCtrl.$scope.logKeys = function($rootScope,$event){
$rootScope.keyLog.shift(); // Remove First Item of Array
$rootScope.keyLog.Push($event.keyCode); // Adds new key press to end of Array
if($scope.$rootScope.keyLog[0] !== 38) { return false; } // 38 == up key
if($scope.$rootScope.keyLog[1] !== 38) { return false; }
if($scope.$rootScope.keyLog[2] !== 40) { return false; } // 40 = down key
if($scope.$rootScope.keyLog[3] !== 40) { return false; }
if($scope.$rootScope.keyLog[4] !== 27) { return false; } // 37 = left key
if($scope.$rootScope.keyLog[5] !== 39) { return false; } // 39 = right key
if($scope.$rootScope.keyLog[6] !== 37) { return false; }
if($scope.$rootScope.keyLog[7] !== 39) { return false; }
if($scope.$rootScope.keyLog[8] !== 65) { return false; } // 65 = a
if($scope.$rootScope.keyLog[9] !== 66) { return false; } // 66 = b
$rootScope.doThisWhenAllKeysPressed(); // Got this far, must all match!
return true;
}
En dehors d'un champ de saisie, je ne pense pas que ng-keypress fonctionne, mais le fait d'appuyer sur la touche depuis angular-ui might.
Je suis sûr qu'il devrait y avoir une fonction de type tableau diff aussi, mais l'appel spécifique m'évite maintenant.
Voici mon point de vue sur elle:
var app = angular.module('contra', []);
app.directive('code', function () {
function codeState() {
this.currentState = 0;
this.keys = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65];
this.keyPressed = function (key) {
if (this.keys[this.currentState] == key) {
this.currentState++;
if (this.currentState == this.keys.length) {
this.currentState = 0;
return true;
}
} else {
this.currentState = 0;
}
return false;
};
};
return {
restrict: 'A',
link: function (scope, element, attrs) {
var cs = new codeState();
scope.isValid = "NO";
element.bind("keydown", function (event) {
scope.$apply(function () {
if (cs.keyPressed(event.which)) {
scope.isValid = "YES";
console.log("CODE ENTERED");
} else {
scope.isValid = "NO";
}
});
});
}
}
});
Ce qui est différent à ce sujet, c’est qu’il s’agit d’une directive. Par conséquent, si vous l’attachez sur le corps, cela s’appliquera à la page entière. Cela permet également de saisir le code plusieurs fois.
Plunkr:
Découvrez ce plunker . J'ai mis en place un scénario simple "2 frappes de touche en rangée".
Vous pouvez le faire en clair jQuery et communiquer l'événement avec un $rootScope.$broadcast
.
Enregistrez le code jQuery dans et Angular run
callback (garantit que angular a déjà été bootstraped):
app.run(function($rootScope) {
var upHitOnce = false;
$(document).keyup(function(event) {
if (event.which == 38) {
if (upHitOnce) {
$rootScope.$broadcast('DoubleUpFired');
$rootScope.$apply();
upHitOnce = false;
} else {
upHitOnce = true;
}
} else {
upHitOnce = false;
}
});
});
et alors tout contrôleur peut écouter cet événement comme:
$scope.$on('DoubleUpFired', function() {
$scope.fired = true;
});
Lier un rappel d'action ng-keydown
à body
est correct, mais présente un léger inconvénient. Il déclenche un $digest
sur chaque frappe. Ce que vous voulez vraiment, c'est un $digest
uniquement lorsque la séquence a été entrée et que vous devez d'une manière ou d'une autre mettre à jour l'interface utilisateur.
Voir les commentaires sur la façon de supprimer la dépendance actuelle de jQuery.
Si vous essayez 'ctrl + s' ou 'commond + s' (changez la commondKey) pour faire une sauvegarde, vous pouvez peut-être utiliser comme ça:
directive:
(function () {
'use strict';
var lastKey = 0;
//var commondKey = 17;
var commondKey = 91;
angular
.module('xinshu')
.directive('saveEnter', function () {
return function (scope, element, attrs) {
element.bind("keydown", function (event) {
if (event.which != commondKey && event.which != 83) {
lastKey = 0;
}
if (lastKey == commondKey && event.which == 83) {
scope.$apply(function () {
scope.$eval(attrs.saveEnter);
});
event.preventDefault();
}
lastKey = event.which;
});
};
});
})();
élément:
<input id="title" save-enter="vm.saveTitle()"/>
Vous pouvez renommer la directive saveEnter dans, en modifiant la commande save-enter en HTML.
Le 'vm.saveTitle ()' est la fonction que vous voulez faire.