【问题标题】:Clear input text field in Angular / AngularUI with ESC key使用 ESC 键清除 Angular / AngularUI 中的输入文本字段
【发布时间】:2013-01-16 19:17:53
【问题描述】:

在我的 Angular 应用程序的几个地方,我需要使用 ESC 键清除用户的输入。问题是,我不知道如何使用文本输入字段(textarea 清除 OK)。看到这个小提琴:

jsFiddle demonstration of the problem

绑定:

<input ng-model="search.query" ui-keypress="{esc: 'keyCallback($event)'}" />

我使用的回调:

$scope.keyCallback = function($event) {
  $event.preventDefault();
  $scope.search.query = '';
}

请谁能弄清楚我需要做什么才能使用 ESC 键清除文本输入

解决方案: 正如bmleite 所建议的那样,您不应该听“keypress”,而应该听'keydown''keyup'。问题是,'keydown' 在 Firefox 中不起作用,所以只有 'keyup' 才起到了监听 ESC 的神奇作用。 ;)

工作小提琴:http://jsfiddle.net/aGpNf/190/

解决方案更新: 最后,我不得不同时监听“keydown”和“keyup”事件。因为在我的情况下,FF 确实将 ESC keydown 上的输入字段重置为以前的状态,所以它弄乱了我的模型。因此,'keyup' 清除模型,'keydown' 检查模型是否为空并执行适当的操作。我还需要手动散焦输入以防止文本重新弹出。:/

【问题讨论】:

  • 您能解释一下解决方案更新是什么意思吗?听起来如果 AngularUI 将您的 keyup 包装在 $scope.$apply() 中,它会帮助您吗?如果是这种情况,您可以打开一个问题吗?我也很好奇你说的文本弹出是什么意思?此外,您可以执行以下操作:ui-keydown="{ 'esc enter': 'keyCallback($event)' }",任一键都会触发事件。
  • 如果有人来到这里并且无法让 esc 在 Chrome 中触发...关闭 Vimium 插件或其他。
  • 这似乎不再适用于 Chrome 或 Firefox。我没有在 IE/Edge 或 Opera 中测试过。

标签: angularjs input angular-ui


【解决方案1】:

IE 10/11 接受的答案does not work。这是一个解决方案based on another question

指令

.directive('escKey', function () {
  return function (scope, element, attrs) {
    element.bind('keydown keypress', function (event) {
      if(event.which === 27) { // 27 = esc key
        scope.$apply(function (){
          scope.$eval(attrs.escKey);
        });

        event.preventDefault();
      }
    });
    scope.$on('$destroy', function() {
        element.unbind('keydown keypress')
    })
  };
})

HTML:

<input ... ng-model="filter.abc" esc-key="resetFilter()" >

Ctrl

$scope.resetFilter = function() {
  $scope.filter.abc = null;
};

【讨论】:

  • eval is evil,您可以使用&amp;以正确的方式将方法绑定到指令,更多信息here
  • 我非常喜欢这个,在一堆东西上使用它之后,我继续为它做一个回购。 github.com/deltreey/angular-esc-key如果你愿意,我会把它转给你,但我很乐意维护它。
  • 请随意,我不介意。当我有时间时,我也会尝试使用@icl7126 的建议来改进解决方案并发送拉取请求。另外,如果您有改进,请随时更新我的​​答案。
  • 如何将元素传递给像 esc-key="resetFilter($event)" 这样的控制器,所以在控制器中我可以获得对象 $event.currentTarget
  • 根据链接的问题,Angular 1.7 的“接受的答案”确实有效
【解决方案2】:

我这样解决这个问题(Controller as vm Syntax):

HTML

<input ... ng-model="vm.item" ng-keyup="vm.checkEvents($event)">

控制器

...
vm.checkEvents = function ($event) {
    if ($event.keyCode == 27) {
        vm.item = "";   
    }
}

【讨论】:

    【解决方案3】:

    监听“keydown”或“keyup”事件而不是“keypress”:

    <input ng-model="search.query" ui-keydown="{esc: 'keyCallback($event)'}" />
    

    【讨论】:

    • 感谢您让我走上正确的道路。在写这个问题之前,我已经尝试过“keydown”,但它在 FF 中不起作用,所以我认为这不是正确的解决方案。根据您的建议,我还尝试了“keyup”,瞧,它成功了(在 FF 和 Chrome 中)。
    • 你也可以直接内联:ui-keydown="{esc: 'search.query=\"\"'}"
    • keypress 事件不会在 Esc 按键上触发。使用 keydown/keyup 就可以了。
    【解决方案4】:

    目前,使用 Angular v4,这可以工作:(keyup.esc)="callback()"

    【讨论】:

    • 这是最好最简单的答案!
    【解决方案5】:

    我已经设法构建了一个 directive 直接清除输入元素的 ng-model 并且在 Firefox 中也可以正常工作。为此,我需要检查该值是否已被清除 (modelGetter(scope)) 并将分配包装到零 $timeout 方法中(以在下一次摘要调用中应用它)。

    mod.directive('escClear', ['$timeout', '$parse', function($timeout, $parse) {
      return {
        link : function(scope, element, attributes, ctrl) {
          var modelGetter = $parse(attributes.ngModel);
          element.bind('keydown', function(e) {
            if (e.keyCode === $.ui.keyCode.ESCAPE && modelGetter(scope)) {
              $timeout(function() {
                scope.$apply(function () {modelGetter.assign(scope, '');});
              }, 0);
            }
          });
        }
      };
    }]);
    

    我的$ 属性是jQuery,请随意将其替换为magic number 27

    【讨论】:

      【解决方案6】:

      Angular 2 版本也更新了 ngModel

      指令

      import { Directive, Output, EventEmitter, ElementRef, HostListener } from '@angular/core';
      
      @Directive({
        selector: '[escapeInput]'
      })
      export class escapeInput {
      
        @Output() ngModelChange: EventEmitter<any> = new EventEmitter();
        private element: HTMLElement;
        private KEY_ESCAPE: number = 27;
      
        constructor(private elementRef: ElementRef) {
          this.element = elementRef.nativeElement;
        }
      
        @HostListener('keyup', ['$event']) onKeyDown(event) {
          if (event.keyCode == this.KEY_ESCAPE) {
            event.target.value = '';
            this.ngModelChange.emit(event.target.value);
          }
        }
      
      }
      

      用法

      <input escapeInput class="form-control" [(ngModel)]="modelValue" type="text" />
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-05-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多