[英]AngularJS: How to handle keyboard shortcuts in routing controllers?
How do you implement page-specific keyboard shortcuts in an AngularJS 1.5 app that uses routing ? 如何在使用路由的AngularJS 1.5应用程序中实现特定于页面的键盘快捷方式 ?
This is what I would like to achieve: 这是我要实现的目标:
index.html: index.html:
<!doctype html>
<html data-ng-app="myApp">
<body data-ng-keydown="onKeyDown($event)">
...
<div data-ng-view></div>
...
</body>
</html>
As I understand, you need to handle key-down events on the <body>
据我了解,您需要处理<body>
上的按键事件<body>
tag, if you don't have elements in the scope that are focused (input fields for example, I don't have those). 标签,如果您在范围内没有重点关注的元素(例如,输入字段,则没有这些元素)。
app.js: app.js:
var myApp = angular.module('myApp', ['ngRoute', 'myControllers']);
myApp.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'pages/home.html',
controller: 'HomeCtrl'
})
.when('/create', {
templateUrl: 'pages/create.html',
controller: 'CreateCtrl'
});
}]);
controllers.js: controllers.js:
var myControllers = angular.module('myControllers', []);
myControllers.controller('HomeCtrl', ['$scope', function ($scope) {
$scope.closeLandingPagePopUp = function () {
...
};
$scope.onKeyDown = function ($event) {
switch ($event.keyCode) {
case 27: // [Esc]
$scope.closeLandingPagePopUp();
break;
...
}
};
}]);
myControllers.controller('CreateCtrl', ['$scope', function ($scope) {
$scope.cancelCreation = function () {
...
};
$scope.onKeyDown = function ($event) {
switch ($event.keyCode) {
case 27: // [Esc]
$scope.cancelCreation();
break;
...
}
};
}]);
So on both pages the [Esc] key should be handled differently. 因此,在两个页面上,[Esc]键应以不同的方式处理。
Of course the HTML attribute data-ng-keydown="onKeyDown($event)"
doesn't work, because it's outside the controllers' scopes. 当然,HTML属性data-ng-keydown="onKeyDown($event)"
不起作用,因为它超出了控制器的范围。
Is there a way to do this while still keeping all page specific code within their respective controller? 有办法做到这一点,同时仍将所有页面特定的代码保留在各自的控制器中吗?
To get events outside of a directive, bind the event handler to $document
. 要获取指令外的事件,请将事件处理程序绑定到$document
。
angular.module('myApp').directive("globalKeydown",
function($document) {
return function linkFn(scope,elem,attrs) {
var handlerUnbind = $document.on("keydown", function(e) {
scope.$eval(attrs.globalKeydown, {$event: e});
scope.$apply();
});
scope.$on('$destroy', function() {
handlerUnbind();
})
}
});
This example directive puts a keydown
event handler on the $document
that invokes the expression defined by the global-event
attribute. 此示例指令将keydown
事件处理程序放在$document
上,该处理程序调用由global-event
属性定义的表达式。 The event is as exposed as $event
. 该事件与$event
一样公开。
<div ng-app="myApp">
<p>Click this window and press any key</p>
<p global-keydown='keycode=($event.code)'>
Global keydown = {{keycode}}
</p>
</div>
The DEMO on JSFiddle . JSFiddle上的DEMO 。
For more information on $event
, see AngularJS Developer Guide -- $event . 有关$event
更多信息,请参见《 AngularJS开发人员指南-$ event》 。
georgeawg's answer was inspiring, but I ended up with this implementation: georgeawg的答案令人鼓舞,但我最终实现了该实现:
myControllers.controller('HomeCtrl', ['$scope', '$document', function ($scope, $document) {
var handleKeyDown = function(event) {
switch (event.keyCode) {
case 27: // [Esc]
$scope.closeLandingPagePopUp();
break;
...
}
$scope.$apply();
};
$document.on('keydown', handleKeyDown);
$scope.$on('$destroy', function() {
$document.unbind('keydown', handleKeyDown);
});
}]);
There is actually nothing to do within the HTML parts. 实际上,HTML部分中没有任何事情要做。
Explanation: 说明:
handleKeyDown(event)
function that implements the shortcuts 每个控制器都有一个实现快捷方式的handleKeyDown(event)
函数 $document.on('keydown', handleKeyDown)
binds the handler function to global keydown events when the controller is initialized. 初始化控制器时$document.on('keydown', handleKeyDown)
将处理函数绑定到全局keydown事件。 $document is Angular's jQuery wrapper. $ document是Angular的jQuery包装器。 $scope.$apply()
to let Angular know when data has changed and the view needs to be refreshed 使用$scope.$apply()
让Angular知道何时数据已更改并且视图需要刷新
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.