What I ended up doing worked surprisingly well, and I'll opensource it as a module after a bit more work.
I created a directive, which binds to the keypress events on $document
angular.module('keypress', []).directive('keypressEvents', function($document, $rootScope) { return { restrict: 'A', link: function() { $document.bind('keypress', function(e) { $rootScope.$broadcast('keypress',e , String.fromCharCode(e.which)); }); } } })
I then created a second directive for watching for keypresses on specific elements, basically giving the element a focus for key events.
angular.module('focus', []).directive('onFocus', function() { return { restrict: 'C', link: function(scope) { scope.$on('keypress',function(e,parent_evt,key){ if(scope.keyBindings[key]){ scope.keyBindings[key](parent_evt, e); // params reversed so user goes up the chain } }); } } });
In any controller where you want to use keyboard shortcuts, add a keybindings object
function keyedS(key, parent_evt, evt){ // key is the key that was pressed // parent_evt is the keypress event // evt is the focused element object } $scope.keyBindings = { 's': keyedS }
Feedback?
I've actually put this together with multiple keybindings, so if the user selects 'ctrl-shift-s', that is what gets passed along the chain. Though I'm still struggling to find a really good way of getting all the press events. Eg. Tab doesn't work at the moment.