用于按键重定向的 AngularJS 代码应该是服务或指令

AngularJS code for redirection on keypress should be a service or a directive?

本文关键字:服务 指令 代码 重定向 AngularJS 用于      更新时间:2023-09-26

当用户从键盘按下特定键时,我需要将用户重定向到特定路由。我的问题是:

根据关注点分离和 AngularJS 最佳实践,此代码应该保留在指令上还是服务上?

我知道应该使用指令来操纵 DOM。因此,考虑到这一点,我创建了以下服务:

myApp.factory("KeyPressEvents", ['$rootScope', '$document', '$location', function($rootScope, $document, $location){
    return $document.bind("keypress", function(event){
        if(event.charCode==112){
            $rootScope.$apply(function(){
                $location.path('/route2');
            });
        }
    });
}]);

在上面的代码中,每当用户按键盘上的 P 时,他都会被重定向到"/route2"。

另一方面,在研究stackoverflow时,我意识到一些答案建议使用指令做几乎相同的事情:

如何在 AngularJS 中使用按键事件?

在 AngularJS 中绑定键盘事件

这就是为什么我仍然不太明白的原因。对这个问题有什么想法吗?谢谢!

IMO,指令不仅限于DOM操作,而且也适用于UI交互。我做了类似的事情来注册一个扫描仪(就我的应用程序而言,它只是"键入"几个字符,后跟一个产品代码)。我将指令贴在 html 标签上(请记住,ng-app也需要在 html 标签上才能正常工作)。虽然你也可以把指令放在文本输入上 - 在我的情况下,它需要在正文上。

<html ng-app="myApp" scanner>

本质上,该指令侦听插入符号字符,如果检测到它,它将使用该ScannerService然后相应地执行重定向。

  myApp.directive('scanner', ["$state", "ScannerService", function ($state, ScannerService){
    return {
      restrict: 'A',
      link: function (scope, elem) {
        elem.bind('keypress', function (e) {
          if (e.which === 94) { // ^
            barcodeListen = true;
          }
          if (barcodeListen === true) {
            if (e.which === 13) { // new-line
              ScannerService.processBarcode(barcodeText);
              barcodeListen = false;
            }
            e.preventDefault(); // don't print character
          }
        });
      }
    };
  }]);

由于我希望快捷方式是应用程序范围的,因此我将代码插入到app.run中,如@DanielWeiner的注释所示。所以,我最终得到了这个:

app.run(['$rootScope', '$document', '$location',
    function($rootScope, $document, $location){
        $document.bind("keypress", function(event) {
            if($('input:focus').length == 0) {
                // If we press the 'j' key, goes to /route2
                if(event.charCode==112){
                    $rootScope.$apply(function(){
                        $location.path('/route2');
                    });
                }
            }
        });
    }
]);

感谢您的回答和评论。