为什么我的事件处理程序总是落后一次击键,$timeout 如何解决这个问题?

问题描述 投票:0回答:4

我完全困惑为什么我的按键事件处理程序总是落后一次击键。 http://plnkr.co/edit/w3FAXGd5zjrktO6DgOpD?p=preview

<body ng-controller="myController">
  <form>
    <input ng-keypress="handleKeypress($event)" />
  </form>
</body>

控制器:

myapp.controller('myController', function($scope, $timeout){

    $scope.handleKeypress = function(ev){

      console.log(ev.target.value); //always one keystroke behind

      //$timeout(function(){console.log(ev.target.value);}); //works!

    };
}); 

为什么 $timeout 是必要的以及它为什么/如何工作? (最好是对新手友好的答案)

我知道在按键事件中角色尚未插入到 DOM 中,但我很困惑,因为 angularjs.org 上的 Hello World 示例在释放按键之前响应。他们的示例没有使用自定义事件处理程序,但显然 Angular 正在 keyup 事件之前更新模型,因此我想了解有关在自定义事件处理程序中执行此操作的更多信息。

idursun 的回答指出 event.which 可在按键上使用,我认为 Angular 可能正在使用

String.fromCharCode()
,但我在 Angular 源代码中没有看到任何与此效果相关的内容。

angularjs angularjs-directive
4个回答
6
投票

您应该使用

ng-keyup
。按键可能并不总是按预期工作。

来自 jQuery 文档:

注意: 由于按键事件未包含在任何官方规范中,因此使用时遇到的实际行为可能会因浏览器、浏览器版本和平台的不同而有所不同。


1
投票

因为示例中的事件目标是一个输入元素,并且该元素尚未处理击键,所以该元素的

value
始终是一个击键滞后。这使事件处理程序有机会拒绝按键。

您可以通过查看事件对象的

which
字段来检查按下的键值。


0
投票

tl:dr - event.target.value + event.key 将为您提供最新值。

之所以落后一步,是因为它允许您通过在注册事件之前触发事件来拒绝按键。这不是一个错误,而是一个功能。

但是如果您想获得最新的值,这里有一个解决方法:-

html:-

<input type="text" (keypress)="myFunction($event)">

JS:-

myFunction(event) {
event.preventDefault()
console.log('latest input field value => ', event.target.value + event.key)
}

更新:-

添加 event.preventDefault() 以避免出现双字符。

更新2:-

事件按以下顺序调用:-

  1. 按键
  2. 按键
  3. 更新视图
  4. 按键
  5. 更新视图
  6. 按键

因此,如果您可以将此事件更改为 keyup 那么您将获得最新的值,而不必在方法中进行额外的更改。


0
投票

它可能会对最新角度的人有所帮助。

我使用(输入)而不是按键,它适用于每个字符的按下。

© www.soinside.com 2019 - 2024. All rights reserved.