$ timeout如何解决这个问题?

时间:2014-01-27 18:41:18

标签: javascript angularjs angularjs-directive

我的按键事件处理程序始终是一个键击,并以某种方式$timeout修复此问题。

<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是必要的,为什么/如何运作?

我理解,对于keypress事件,该字符尚未插入DOM中,但我感到困惑,因为angularjs.org处的Hello World示例在释放密钥之前响应。

(他们的示例不使用自定义事件处理程序,但显然Angular正在keyup事件之前更新模型,因此我想了解更多关于在自定义事件处理程序中执行此操作的信息。)

event.which可在keypresskeydown上找到,我想也许Angular可能正在使用String.fromCharCode(),但我没有在Angular来源中看到任何内容效果。

1 个答案:

答案 0 :(得分:2)

$timeout允许您的函数在当前循环结束时将值添加到字段后的下一个循环中运行。基本上,使用$timeout,您告诉它等待,并等待ev.target.value更新。

就例子而言。 Angular正在运行脏检查,寻找在UI事件上发生变化的事情,这就是它知道更新其值的方式。它发生在按键事件之后。脏检查是基于超时的。您可以在此处看到:http://jsfiddle.net/TheSharpieOne/V6p9M/1/,当您的函数运行时,$ scope不会更新。将日志更改为警报,您会看到DOM未更新。

如果您尝试避免$timeout来电,可以使用ngChange事件。与普通onChange(在blur上触发)不同,每次更改值时都会触发ngChange,例如按键。

http://jsfiddle.net/TheSharpieOne/V6p9M/