I suppose that I should use directive, but it seems strange to add directive to body, but listen events on document.
我想我应该使用指令,但是在正文中添加指令似乎有点奇怪,但是在文档中监听事件。
What is a proper way to do this?
正确的做法是什么?
UPDATE: Found AngularJS UI and saw their realization of keypress directive.
更新:找到AngularJS UI,看到他们实现的按键指令。
12 个解决方案
#1
8
Here's how I've done this with jQuery - I think there's a better way.
下面是我使用jQuery的方法——我认为有更好的方法。
var app = angular.module('angularjs-starter', []);
app.directive('shortcut', function() {
return {
restrict: 'E',
replace: true,
scope: true,
link: function postLink(scope, iElement, iAttrs){
jQuery(document).on('keypress', function(e){
scope.$apply(scope.keyPressed(e));
});
}
};
});
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.keyCode = "";
$scope.keyPressed = function(e) {
$scope.keyCode = e.which;
};
});
<body ng-controller="MainCtrl">
<shortcut></shortcut>
<h1>View keys pressed</h1>
{{keyCode}}
</body>
恰好演示
#2
68
I would say a more proper way (or "Angular way") would be to add it to a directive. Here's a simple one to get you going (just add keypress-events
attribute to <body>
):
我认为一个更合适的方法(或“角度方法”)是将它添加到指令中。这里有一个简单的方法可以让您继续(只需将keypress-events属性添加到):
angular.module('myDirectives', []).directive('keypressEvents', [
'$document',
'$rootScope',
function($document, $rootScope) {
return {
restrict: 'A',
link: function() {
$document.bind('keypress', function(e) {
console.log('Got keypress:', e.which);
$rootScope.$broadcast('keypress', e);
$rootScope.$broadcast('keypress:' + e.which, e);
});
}
};
}
]);
In your directive you can then simply do something like this:
在你的指令中,你可以简单地做如下的事情:
module.directive('myDirective', [
function() {
return {
restrict: 'E',
link: function(scope, el, attrs) {
scope.keyPressed = 'no press :(';
// For listening to a keypress event with a specific code
scope.$on('keypress:13', function(onEvent, keypressEvent) {
scope.keyPressed = 'Enter';
});
// For listening to all keypress events
scope.$on('keypress', function(onEvent, keypressEvent) {
if (keypress.which === 120) {
scope.keyPressed = 'x';
}
else {
scope.keyPressed = 'Keycode: ' + keypressEvent.which;
}
});
},
template: '<h1>{{keyPressed}}</h1>'
};
}
]);
#3
27
Use $document.bind
:
使用$ document.bind:
function FooCtrl($scope, $document) {
...
$document.bind("keypress", function(event) {
console.debug(event)
});
...
}
#4
20
I can't vouch for it just yet but I've started taking a look at AngularHotkeys.js:
我现在还不能保证,但我已经开始研究盎格鲁人。
http://chieffancypants.github.io/angular-hotkeys/
http://chieffancypants.github.io/angular-hotkeys/
Will update with more info once I've got my teeth into it.
一旦我了解了它,将会更新更多的信息。
Update 1: Oh there's a nuget package: angular-hotkeys
更新1:哦,有一个nuget包:angular-hotkeys
Update 2: actually very easy to use, just set up your binding either in your route or as I'm doing, in your controller:
更新2:实际上很容易使用,在你的路径或者像我一样,在你的控制器中设置你的绑定:
hotkeys.add('n', 'Create a new Category', $scope.showCreateView);
hotkeys.add('e', 'Edit the selected Category', $scope.showEditView);
hotkeys.add('d', 'Delete the selected Category', $scope.remove);
#5
10
Here's an example of an AngularJS service for keyboard shortcuts: http://jsfiddle.net/firehist/nzUBg/
这里有一个用于键盘快捷方式的AngularJS服务示例:http://jsfiddle.net/firehist/nzUBg/
It can then be used like this:
然后可以这样使用:
function MyController($scope, $timeout, keyboardManager) {
// Bind ctrl+shift+d
keyboardManager.bind('ctrl+shift+d', function() {
console.log('Callback ctrl+shift+d');
});
}
Update: I'm now using angular-hotkeys instead.
更新:我现在使用的是angular-hotkeys。
#6
6
As a Directive
作为一个指令
This is essentially how it is done in the Angular documentation code, i.e. pressing /
to start searching.
这基本上就是角化文档代码的实现方式,即按/开始搜索。
angular
.module("app", [])
.directive("keyboard", keyboard);
function keyboard($document) {
return {
link: function(scope, element, attrs) {
$document.on("keydown", function(event) {
// if keycode...
event.stopPropagation();
event.preventDefault();
scope.$apply(function() {
// update scope...
});
}
};
}
Plunk using a keyboard directive
使用键盘指令
http://plnkr.co/edit/C61Gnn?p=preview
http://plnkr.co/edit/C61Gnn?p=preview
As a Service
作为服务
Converting that directive into a service is real easy. The only real difference is that the scope is not exposed on the service. To trigger a digest, you can bring in the $rootScope
or use a $timeout
.
将该指令转换为服务非常容易。惟一真正的区别是服务的范围没有公开。要触发摘要,可以引入$rootScope或使用$timeout。
function Keyboard($document, $timeout, keyCodes) {
var _this = this;
this.keyHandlers = {};
$document.on("keydown", function(event) {
var keyDown = _this.keyHandlers[event.keyCode];
if (keyDown) {
event.preventDefault();
$timeout(function() {
keyDown.callback();
});
}
});
this.on = function(keyName, callback) {
var keyCode = keyCodes[keyName];
this.keyHandlers[keyCode] = { callback: callback };
return this;
};
}
You can now register callbacks in your controller using the keyboard.on()
method.
现在可以使用keyboard.on()方法在控制器中注册回调。
function MainController(keyboard) {
keyboard
.on("ENTER", function() { // do something... })
.on("DELETE", function() { // do something... })
.on("SHIFT", function() { // do something... })
.on("INSERT", function() { // do something... });
}
Alternate version of Plunk using a service
使用服务的另一个版本
http://plnkr.co/edit/z9edu5?p=preview
http://plnkr.co/edit/z9edu5?p=preview
#7
4
The slightly shorter answer is just look at solution 3 below. If you would like to know more options, you could read the whole thing.
稍短的答案是下面的解决方案3。如果你想知道更多的选项,你可以阅读整篇文章。
I agree with jmagnusson. But I believe there is cleaner solution. Instead of binding the keys with functions in directive, you should be able just bind them in html like defining a config file, and the hot keys should be contextual.
我同意jmagnusson。但我相信有更干净的解决办法。与其将键与指令中的函数绑定在一起,不如像定义配置文件那样将键绑定到html中,而热键应该是上下文相关的。
-
Below is a version that use mouse trap with a custom directive. (I wasn't the author of this fiddle.)
下面是一个使用带有自定义指令的鼠标陷阱的版本。(我不是这个小提琴的作者。)
var app = angular.module('keyExample', []); app.directive('keybinding', function () { return { restrict: 'E', scope: { invoke: '&' }, link: function (scope, el, attr) { Mousetrap.bind(attr.on, scope.invoke); } }; }); app.controller('RootController', function ($scope) { $scope.gotoInbox = function () { alert('Goto Inbox'); }; }); app.controller('ChildController', function ($scope) { $scope.gotoLabel = function (label) { alert('Goto Label: ' + label); }; });
You will need to include mousetrap.js, and you use it like below:
你需要包括捕鼠器。js,使用方式如下:
<div ng-app="keyExample"> <div ng-controller="RootController"> <keybinding on="g i" invoke="gotoInbox()" /> <div ng-controller="ChildController"> <keybinding on="g l" invoke="gotoLabel('Sent')" /> </div> </div> <div>Click in here to gain focus and then try the following key strokes</div> <ul> <li>"g i" to show a "Goto Inbox" alert</li> <li>"g l" to show a "Goto Label" alert</li> </ul> </div>
http://jsfiddle.net/BM2gG/3/
The solution require you to include mousetrap.js which is library that help you to define hotkeys.
解决方案要求您包含mousetrap。js是一个库,可以帮助您定义热键。
-
If you want to avoid the trouble to develop your own custom directive, you can check out this lib:
如果你想避免开发你自己的自定义指令的麻烦,你可以看看这个库:
https://github.com/drahak/angular-hotkeys
https://github.com/drahak/angular-hotkeys
And this
这
https://github.com/chieffancypants/angular-hotkeys
https://github.com/chieffancypants/angular-hotkeys
The second one provide a bit more features and flexibility, i.e. automatic generated hot key cheat sheet for your app.
第二个版本提供了更多的特性和灵活性,即自动生成应用程序的热门密钥备忘单。
Update: solution 3 is no longer available from Angular ui.
更新:解决方案3不再适用于角ui。
-
Apart from the solutions above, there is another implementation done by angularui team. But the downside is the solution depends on JQuery lib which is not the trend in the angular community. (Angular community try to just use the jqLite that comes with angularjs and get away from overkilled dependencies.) Here is the link
除了上面的解决方案,angularui团队还完成了另一个实现。但缺点是解决方案依赖于JQuery lib,而这在棱角分明的社区中并不流行。(有棱角的社区尝试使用jqLite,它带有angularjs,可以避免过度依赖。)这里是链接
http://angular-ui.github.io/ui-utils/#/keypress
http://angular-ui.github.io/ui-utils/ /键盘按键
The usage is like this:
用法是这样的:
In your html, use the ui-keydown attribute to bind key and functions.
在html中,使用ui-keydown属性绑定键和函数。
<div class="modal-inner" ui-keydown="{
esc: 'cancelModal()',
tab: 'tabWatch($event)',
enter: 'initOrSetModel()'
}">
In your directive, add those functions in your scope.
在您的指令中,将这些函数添加到您的范围中。
app.directive('yourDirective', function () {
return {
restrict: 'E',
templateUrl: 'your-html-template-address.html'
link: function(){
scope.cancelModal() = function (){
console.log('cancel modal');
};
scope.tabWatch() = function (){
console.log('tabWatch');
};
scope.initOrSetModel() = function (){
console.log('init or set model');
};
}
};
});
After playing around with all of the solutions, I would recommend the one that is implemented by Angular UI team, solution 3 which avoided many small strange issues I have encountered.
在处理完所有的解决方案之后,我将推荐由角UI团队实现的解决方案3,它避免了我遇到的许多小的奇怪问题。
#8
1
I made a service for shortcuts.
我提供快捷键服务。
It looks like:
它看起来像:
angular.module('myApp.services.shortcuts', [])
.factory('Shortcuts', function($rootScope) {
var service = {};
service.trigger = function(keycode, items, element) {
// write the shortcuts logic here...
}
return service;
})
And I injected it into a controller:
我把它注射到控制器中
angular.module('myApp.controllers.mainCtrl', [])
.controller('mainCtrl', function($scope, $element, $document, Shortcuts) {
// whatever blah blah
$document.on('keydown', function(){
// skip if it focused in input tag
if(event.target.tagName !== "INPUT") {
Shortcuts.trigger(event.which, $scope.items, $element);
}
})
})
It works, but you may notice that I inject $element and $document into the controller.
它可以工作,但是您可能注意到我将$element和$document注入到控制器中。
It's a bad controller practice and violates the 'Dont EVER access $element in the controller' convention.
这是一个糟糕的控制器实践,违反了“从未访问控制器”约定中的$元素。
I should put it into directive, then use 'ngKeydown' and $event to trigger the service.
我应该把它放入指令,然后使用'ngKeydown'和$event触发服务。
But I think the service is fine and I will rework the controller sooner.
但我认为服务是好的,我将尽快重新工作控制器。
updated:
更新:
It seems like 'ng-keydown' only works in input tags.
它看起来像“ng-keydown”只在输入标签中工作。
So I just write a directive and inject $document:
所以我写了一个指令,然后注入$document:
angular.module('myApp.controllers.mainCtrl', [])
.directive('keyboard', function($scope, $document, Shortcuts) {
// whatever blah blah
return {
link: function(scope, element, attrs) {
scope.items = ....;// something not important
$document.on('keydown', function(){
// skip if it focused in input tag
if(event.target.tagName !== "INPUT") {
Shortcuts.trigger(event.which, scope.items, element);
}
})
}
}
})
It's better.
这是更好的。
#9
0
Check this example from the guys behid ng-newsletter.com; check their tutorial on creating a 2048 game, it has some nice code using a service for keyboard events.
查看一下这个例子,来自behid ng-newsletter网站;查看一下他们关于创建2048游戏的教程,它有一些不错的代码,使用键盘事件服务。
#10
0
The following let's you write all your shortcut logic in your controller and the directive will take care of everything else.
下面让我们在控制器中编写所有的快捷方式逻辑,指令将处理所有其他的事情。
Directive
指令
.directive('shortcuts', ['$document', '$rootScope', function($document, $rootScope) {
$rootScope.shortcuts = [];
$document.on('keydown', function(e) {
// Skip if it focused in input tag.
if (event.target.tagName !== "INPUT") {
$rootScope.shortcuts.forEach(function(eventHandler) {
// Skip if it focused in input tag.
if (event.target.tagName !== 'INPUT' && eventHandler)
eventHandler(e.originalEvent, e)
});
}
})
return {
restrict: 'A',
scope: {
'shortcuts': '&'
},
link: function(scope, element, attrs) {
$rootScope.shortcuts.push(scope.shortcuts());
}
};
}])
Controller
控制器
$scope.keyUp = function(key) {
// H.
if (72 == key.keyCode)
$scope.toggleHelp();
};
Html
Html
<div shortcuts="keyUp">
<!-- Stuff -->
</div>
#11
0
you can try this library it made it very easy to manage hot keys, it automatically binds and unbinds keys as you navigate the app
你可以尝试这个库它使管理热键变得非常容易,它自动绑定和解除绑定键,当你在应用中导航
angular-hotkeys
#12
0
i don't know if it's a real angular way, but what i've done
我不知道这是否是一个真正的角度,但我已经做了。
$(document).on('keydown', function(e) {
$('.button[data-key=' + String.fromCharCode(e.which) + ']').click();
});
<div class="button" data-key="1" ng-click="clickHandler($event)">
ButtonLabel
</div>
#1
8
Here's how I've done this with jQuery - I think there's a better way.
下面是我使用jQuery的方法——我认为有更好的方法。
var app = angular.module('angularjs-starter', []);
app.directive('shortcut', function() {
return {
restrict: 'E',
replace: true,
scope: true,
link: function postLink(scope, iElement, iAttrs){
jQuery(document).on('keypress', function(e){
scope.$apply(scope.keyPressed(e));
});
}
};
});
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.keyCode = "";
$scope.keyPressed = function(e) {
$scope.keyCode = e.which;
};
});
<body ng-controller="MainCtrl">
<shortcut></shortcut>
<h1>View keys pressed</h1>
{{keyCode}}
</body>
恰好演示
#2
68
I would say a more proper way (or "Angular way") would be to add it to a directive. Here's a simple one to get you going (just add keypress-events
attribute to <body>
):
我认为一个更合适的方法(或“角度方法”)是将它添加到指令中。这里有一个简单的方法可以让您继续(只需将keypress-events属性添加到):
angular.module('myDirectives', []).directive('keypressEvents', [
'$document',
'$rootScope',
function($document, $rootScope) {
return {
restrict: 'A',
link: function() {
$document.bind('keypress', function(e) {
console.log('Got keypress:', e.which);
$rootScope.$broadcast('keypress', e);
$rootScope.$broadcast('keypress:' + e.which, e);
});
}
};
}
]);
In your directive you can then simply do something like this:
在你的指令中,你可以简单地做如下的事情:
module.directive('myDirective', [
function() {
return {
restrict: 'E',
link: function(scope, el, attrs) {
scope.keyPressed = 'no press :(';
// For listening to a keypress event with a specific code
scope.$on('keypress:13', function(onEvent, keypressEvent) {
scope.keyPressed = 'Enter';
});
// For listening to all keypress events
scope.$on('keypress', function(onEvent, keypressEvent) {
if (keypress.which === 120) {
scope.keyPressed = 'x';
}
else {
scope.keyPressed = 'Keycode: ' + keypressEvent.which;
}
});
},
template: '<h1>{{keyPressed}}</h1>'
};
}
]);
#3
27
Use $document.bind
:
使用$ document.bind:
function FooCtrl($scope, $document) {
...
$document.bind("keypress", function(event) {
console.debug(event)
});
...
}
#4
20
I can't vouch for it just yet but I've started taking a look at AngularHotkeys.js:
我现在还不能保证,但我已经开始研究盎格鲁人。
http://chieffancypants.github.io/angular-hotkeys/
http://chieffancypants.github.io/angular-hotkeys/
Will update with more info once I've got my teeth into it.
一旦我了解了它,将会更新更多的信息。
Update 1: Oh there's a nuget package: angular-hotkeys
更新1:哦,有一个nuget包:angular-hotkeys
Update 2: actually very easy to use, just set up your binding either in your route or as I'm doing, in your controller:
更新2:实际上很容易使用,在你的路径或者像我一样,在你的控制器中设置你的绑定:
hotkeys.add('n', 'Create a new Category', $scope.showCreateView);
hotkeys.add('e', 'Edit the selected Category', $scope.showEditView);
hotkeys.add('d', 'Delete the selected Category', $scope.remove);
#5
10
Here's an example of an AngularJS service for keyboard shortcuts: http://jsfiddle.net/firehist/nzUBg/
这里有一个用于键盘快捷方式的AngularJS服务示例:http://jsfiddle.net/firehist/nzUBg/
It can then be used like this:
然后可以这样使用:
function MyController($scope, $timeout, keyboardManager) {
// Bind ctrl+shift+d
keyboardManager.bind('ctrl+shift+d', function() {
console.log('Callback ctrl+shift+d');
});
}
Update: I'm now using angular-hotkeys instead.
更新:我现在使用的是angular-hotkeys。
#6
6
As a Directive
作为一个指令
This is essentially how it is done in the Angular documentation code, i.e. pressing /
to start searching.
这基本上就是角化文档代码的实现方式,即按/开始搜索。
angular
.module("app", [])
.directive("keyboard", keyboard);
function keyboard($document) {
return {
link: function(scope, element, attrs) {
$document.on("keydown", function(event) {
// if keycode...
event.stopPropagation();
event.preventDefault();
scope.$apply(function() {
// update scope...
});
}
};
}
Plunk using a keyboard directive
使用键盘指令
http://plnkr.co/edit/C61Gnn?p=preview
http://plnkr.co/edit/C61Gnn?p=preview
As a Service
作为服务
Converting that directive into a service is real easy. The only real difference is that the scope is not exposed on the service. To trigger a digest, you can bring in the $rootScope
or use a $timeout
.
将该指令转换为服务非常容易。惟一真正的区别是服务的范围没有公开。要触发摘要,可以引入$rootScope或使用$timeout。
function Keyboard($document, $timeout, keyCodes) {
var _this = this;
this.keyHandlers = {};
$document.on("keydown", function(event) {
var keyDown = _this.keyHandlers[event.keyCode];
if (keyDown) {
event.preventDefault();
$timeout(function() {
keyDown.callback();
});
}
});
this.on = function(keyName, callback) {
var keyCode = keyCodes[keyName];
this.keyHandlers[keyCode] = { callback: callback };
return this;
};
}
You can now register callbacks in your controller using the keyboard.on()
method.
现在可以使用keyboard.on()方法在控制器中注册回调。
function MainController(keyboard) {
keyboard
.on("ENTER", function() { // do something... })
.on("DELETE", function() { // do something... })
.on("SHIFT", function() { // do something... })
.on("INSERT", function() { // do something... });
}
Alternate version of Plunk using a service
使用服务的另一个版本
http://plnkr.co/edit/z9edu5?p=preview
http://plnkr.co/edit/z9edu5?p=preview
#7
4
The slightly shorter answer is just look at solution 3 below. If you would like to know more options, you could read the whole thing.
稍短的答案是下面的解决方案3。如果你想知道更多的选项,你可以阅读整篇文章。
I agree with jmagnusson. But I believe there is cleaner solution. Instead of binding the keys with functions in directive, you should be able just bind them in html like defining a config file, and the hot keys should be contextual.
我同意jmagnusson。但我相信有更干净的解决办法。与其将键与指令中的函数绑定在一起,不如像定义配置文件那样将键绑定到html中,而热键应该是上下文相关的。
-
Below is a version that use mouse trap with a custom directive. (I wasn't the author of this fiddle.)
下面是一个使用带有自定义指令的鼠标陷阱的版本。(我不是这个小提琴的作者。)
var app = angular.module('keyExample', []); app.directive('keybinding', function () { return { restrict: 'E', scope: { invoke: '&' }, link: function (scope, el, attr) { Mousetrap.bind(attr.on, scope.invoke); } }; }); app.controller('RootController', function ($scope) { $scope.gotoInbox = function () { alert('Goto Inbox'); }; }); app.controller('ChildController', function ($scope) { $scope.gotoLabel = function (label) { alert('Goto Label: ' + label); }; });
You will need to include mousetrap.js, and you use it like below:
你需要包括捕鼠器。js,使用方式如下:
<div ng-app="keyExample"> <div ng-controller="RootController"> <keybinding on="g i" invoke="gotoInbox()" /> <div ng-controller="ChildController"> <keybinding on="g l" invoke="gotoLabel('Sent')" /> </div> </div> <div>Click in here to gain focus and then try the following key strokes</div> <ul> <li>"g i" to show a "Goto Inbox" alert</li> <li>"g l" to show a "Goto Label" alert</li> </ul> </div>
http://jsfiddle.net/BM2gG/3/
The solution require you to include mousetrap.js which is library that help you to define hotkeys.
解决方案要求您包含mousetrap。js是一个库,可以帮助您定义热键。
-
If you want to avoid the trouble to develop your own custom directive, you can check out this lib:
如果你想避免开发你自己的自定义指令的麻烦,你可以看看这个库:
https://github.com/drahak/angular-hotkeys
https://github.com/drahak/angular-hotkeys
And this
这
https://github.com/chieffancypants/angular-hotkeys
https://github.com/chieffancypants/angular-hotkeys
The second one provide a bit more features and flexibility, i.e. automatic generated hot key cheat sheet for your app.
第二个版本提供了更多的特性和灵活性,即自动生成应用程序的热门密钥备忘单。
Update: solution 3 is no longer available from Angular ui.
更新:解决方案3不再适用于角ui。
-
Apart from the solutions above, there is another implementation done by angularui team. But the downside is the solution depends on JQuery lib which is not the trend in the angular community. (Angular community try to just use the jqLite that comes with angularjs and get away from overkilled dependencies.) Here is the link
除了上面的解决方案,angularui团队还完成了另一个实现。但缺点是解决方案依赖于JQuery lib,而这在棱角分明的社区中并不流行。(有棱角的社区尝试使用jqLite,它带有angularjs,可以避免过度依赖。)这里是链接
http://angular-ui.github.io/ui-utils/#/keypress
http://angular-ui.github.io/ui-utils/ /键盘按键
The usage is like this:
用法是这样的:
In your html, use the ui-keydown attribute to bind key and functions.
在html中,使用ui-keydown属性绑定键和函数。
<div class="modal-inner" ui-keydown="{
esc: 'cancelModal()',
tab: 'tabWatch($event)',
enter: 'initOrSetModel()'
}">
In your directive, add those functions in your scope.
在您的指令中,将这些函数添加到您的范围中。
app.directive('yourDirective', function () {
return {
restrict: 'E',
templateUrl: 'your-html-template-address.html'
link: function(){
scope.cancelModal() = function (){
console.log('cancel modal');
};
scope.tabWatch() = function (){
console.log('tabWatch');
};
scope.initOrSetModel() = function (){
console.log('init or set model');
};
}
};
});
After playing around with all of the solutions, I would recommend the one that is implemented by Angular UI team, solution 3 which avoided many small strange issues I have encountered.
在处理完所有的解决方案之后,我将推荐由角UI团队实现的解决方案3,它避免了我遇到的许多小的奇怪问题。
#8
1
I made a service for shortcuts.
我提供快捷键服务。
It looks like:
它看起来像:
angular.module('myApp.services.shortcuts', [])
.factory('Shortcuts', function($rootScope) {
var service = {};
service.trigger = function(keycode, items, element) {
// write the shortcuts logic here...
}
return service;
})
And I injected it into a controller:
我把它注射到控制器中
angular.module('myApp.controllers.mainCtrl', [])
.controller('mainCtrl', function($scope, $element, $document, Shortcuts) {
// whatever blah blah
$document.on('keydown', function(){
// skip if it focused in input tag
if(event.target.tagName !== "INPUT") {
Shortcuts.trigger(event.which, $scope.items, $element);
}
})
})
It works, but you may notice that I inject $element and $document into the controller.
它可以工作,但是您可能注意到我将$element和$document注入到控制器中。
It's a bad controller practice and violates the 'Dont EVER access $element in the controller' convention.
这是一个糟糕的控制器实践,违反了“从未访问控制器”约定中的$元素。
I should put it into directive, then use 'ngKeydown' and $event to trigger the service.
我应该把它放入指令,然后使用'ngKeydown'和$event触发服务。
But I think the service is fine and I will rework the controller sooner.
但我认为服务是好的,我将尽快重新工作控制器。
updated:
更新:
It seems like 'ng-keydown' only works in input tags.
它看起来像“ng-keydown”只在输入标签中工作。
So I just write a directive and inject $document:
所以我写了一个指令,然后注入$document:
angular.module('myApp.controllers.mainCtrl', [])
.directive('keyboard', function($scope, $document, Shortcuts) {
// whatever blah blah
return {
link: function(scope, element, attrs) {
scope.items = ....;// something not important
$document.on('keydown', function(){
// skip if it focused in input tag
if(event.target.tagName !== "INPUT") {
Shortcuts.trigger(event.which, scope.items, element);
}
})
}
}
})
It's better.
这是更好的。
#9
0
Check this example from the guys behid ng-newsletter.com; check their tutorial on creating a 2048 game, it has some nice code using a service for keyboard events.
查看一下这个例子,来自behid ng-newsletter网站;查看一下他们关于创建2048游戏的教程,它有一些不错的代码,使用键盘事件服务。
#10
0
The following let's you write all your shortcut logic in your controller and the directive will take care of everything else.
下面让我们在控制器中编写所有的快捷方式逻辑,指令将处理所有其他的事情。
Directive
指令
.directive('shortcuts', ['$document', '$rootScope', function($document, $rootScope) {
$rootScope.shortcuts = [];
$document.on('keydown', function(e) {
// Skip if it focused in input tag.
if (event.target.tagName !== "INPUT") {
$rootScope.shortcuts.forEach(function(eventHandler) {
// Skip if it focused in input tag.
if (event.target.tagName !== 'INPUT' && eventHandler)
eventHandler(e.originalEvent, e)
});
}
})
return {
restrict: 'A',
scope: {
'shortcuts': '&'
},
link: function(scope, element, attrs) {
$rootScope.shortcuts.push(scope.shortcuts());
}
};
}])
Controller
控制器
$scope.keyUp = function(key) {
// H.
if (72 == key.keyCode)
$scope.toggleHelp();
};
Html
Html
<div shortcuts="keyUp">
<!-- Stuff -->
</div>
#11
0
you can try this library it made it very easy to manage hot keys, it automatically binds and unbinds keys as you navigate the app
你可以尝试这个库它使管理热键变得非常容易,它自动绑定和解除绑定键,当你在应用中导航
angular-hotkeys
#12
0
i don't know if it's a real angular way, but what i've done
我不知道这是否是一个真正的角度,但我已经做了。
$(document).on('keydown', function(e) {
$('.button[data-key=' + String.fromCharCode(e.which) + ']').click();
});
<div class="button" data-key="1" ng-click="clickHandler($event)">
ButtonLabel
</div>