AngularJS: Как обрабатывать сочетания клавиш в контроллерах маршрутизации?

0

Как реализовать узлы быстрого доступа к страницам в приложении AngularJS 1.5, которое использует маршрутизацию?

Это то, чего я хотел бы достичь:

index.html:

<!doctype html>
<html data-ng-app="myApp">
<body data-ng-keydown="onKeyDown($event)">
    ...
    <div data-ng-view></div>
    ...
</body>
</html>

Насколько я понимаю, вам нужно обрабатывать события с клавиатурой на &lt;body&gt; тег, если у вас нет элементов в области, которые сфокусированы (поля ввода, например, у меня их нет).

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:

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;
            ...
        }
    };
}]);

Поэтому на обеих страницах клавиша [Esc] должна обрабатываться по-разному.

Конечно, атрибут HTML- data-ng-keydown="onKeyDown($event)" не работает, поскольку он находится вне областей контроллеров.

Есть ли способ сделать это, сохраняя при этом весь код, специфичный для каждой страницы, в своем соответствующем контроллере?

  • 0
    Вы должны использовать маленькие директивы, а не контроллеры для этого.
Теги:
angular-ui-router
keyboard-shortcuts
angularjs-directive

2 ответа

0
Лучший ответ

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);
    });
}]);

Внутри частей HTML нечего делать.

Объяснение:

  1. Каждый контроллер имеет функцию handleKeyDown(event) которая реализует ярлыки
  2. $document.on('keydown', handleKeyDown) связывает функцию обработчика с глобальными событиями при $document.on('keydown', handleKeyDown) когда контроллер инициализируется. $ document - Угловая обертка jQuery.
  3. Отвяжите обработчик, когда контроллер будет уничтожен
  4. Используйте $scope.$apply() чтобы Angular узнал, когда данные изменились, и представление нужно обновить
1

Глобальная Директива по Keydown

Чтобы получить события за пределами директивы, привяжите обработчик события к $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();
        })
    }
});

В этом примере директива помещает keydown обработчика события на $document, который вызывает выражение, определенное с помощью global-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>

ДЕМО на JSFiddle.

Дополнительную информацию о $event см. В Руководстве разработчика AngularJS - $ event.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню