在Angular中检测ng-repeat中的鼠标+键盘事件

nav*_*pai 7 javascript angularjs angularjs-directive angularjs-ng-repeat

我有一个应用程序,我使用ng-repeat生成一组跨度,每个跨度都有一个唯一的id(比方说span-{{$index}}).现在我要执行以下操作:

  • 如果我点击跨度,我希望复制跨度的id.我设法通过ng-click执行此操作.
  • 我想进一步扩展这一功能来检测多次点击,以获得所选择的ID数组,但只有CTRL的点击中键被按下.

例如.如果我选择了带有id 1,3,5,7的span的ctrl按钮,我的数组应该有[1,3,5,7],但是如果我没有按下CTRL键那么我应该只有[7],因为它是最后选择的跨度.

另外,我可以绑定相关事件吗?例如,如果我选择id为1的span,如果我单击CTRL+DOWN_ARROW,则同时选择id 2 ...然后是id 3,依此类推,直到我继续按下DOWN_ARROW.

我想我最接近这种类型的用户体验是在撰写新邮件时选择Gmail中的联系人.我可以使用各种键盘和鼠标组合选择联系人.我正在寻找一些非常相似的东西

gmail截图

我正在玩不同的UX技术,但我仍然坚持我用角度来做到这一点.

And*_*son 4

对于您的第一个问题,请参阅下面的 plunkr。

如果将 $event 传递给 ng-click 函数,您可以在控制器中访问该事件。在我的示例中,我检查了 altKey 是否为 true,即检查 alt 键是否在单击的同时按下。您还可以访问 ctrlKey、shiftKey 以及按下的鼠标按钮。请参阅此处的 MouseEvent 对象 - http://www.w3schools.com/jsref/dom_obj_event.asp

控制器:

angular.module('exampleApp', [])

.controller("ItemCtrl", function($scope){

    $scope.items = [
      {text: "Bob", id: 1},
      {text: "Alice", id: 2},
      {text: "Frank", id: 3},
      {text: "Lisa", id: 4}
    ];
    $scope.itemList = [];

    $scope.addItemIdToList = function(event, item){
        if(event.altKey){
          if(isItemInList(item)){
            removeItemIdFromList(item);
          } else {
            addItemIdToList(item);
          }
        } else {
          addItemIdAsSingleSelection(item);
        }
    };

    var isItemInList = function(item){
      var indexOfItem = $scope.itemList.indexOf(item.id);
      return indexOfItem > -1;
    }

    var removeItemIdFromList = function(item){
      var indexOfItem = $scope.itemList.indexOf(item.id);
      $scope.itemList.splice(indexOfItem, 1);
    };

    var addItemIdToList = function(item){
      $scope.itemList.push(item.id);
    };

    var addItemIdAsSingleSelection = function(item){
      $scope.itemList = [item.id];
    };
})
Run Code Online (Sandbox Code Playgroud)

http://plnkr.co/edit/RAX5oxkTomXxryp0sNNc

当逻辑开始变得更加复杂时,最好在指令中执行此类操作。

对于第二个问题,基本部分可以在以下示例中看到:

angular.module('exampleApp', [])

.directive('keypressEvents', function ($document, $rootScope) {
    return {
        restrict: 'E',
        link: function () {
            console.log('linked');
            $document.on('keypress', function(e) {
                if(e.altKey){
                    var s = 223;
                    var a = 229;
                    if(e.which == s){
                      $rootScope.$broadcast("add_next_id");
                    } else if(e.which == a){
                      $rootScope.$broadcast("remove_last_id");
                    }
                }
            })
        }
    }
})

.controller("ItemCtrl", function($scope, $rootScope){

      $scope.items = [
      {text: "Bob", id: 1},
      {text: "Alice", id: 2},
      {text: "Frank", id: 3},
      {text: "Lisa", id: 4}
    ];

    $scope.itemList = [1];

    $rootScope.$on('add_next_id', function (evt, obj, key) {
        $scope.$apply(function () {
            addNextId();
        });
    });

    $rootScope.$on('remove_last_id', function (evt, obj, key) {
        $scope.$apply(function () {
            removeLastId();
        });
    });

    var addNextId = function(){
        var lastId = $scope.itemList[$scope.itemList.length - 1];
        if(lastId < $scope.items.length){
          $scope.itemList.push(lastId+1); 
        }
    };

    var removeLastId = function(){
        if($scope.itemList.length > 1){
          $scope.itemList.pop();
        }
    };

     $scope.isItemInList = function(item){
      var indexOfItem = $scope.itemList.indexOf(item.id);
      return indexOfItem > -1;
    }
})
Run Code Online (Sandbox Code Playgroud)

http://plnkr.co/edit/PyyjfRMovygeq9qNbzWo

我们监听文档中的按键情况并再次检查 altKey。然后,如果 keyCode 是我们的热键之一,我们将使用 $rootScope.$broadcast() 向 $rootScope 发送一条消息,控制器正在使用 $rootScope.$on() 方法监听该消息。

在上面的示例中,alt+s 将添加更多 id,而 alt+a 会将它们删除到最初选择的 id。