Javascript Angularjs焦点意外地需要异步setTimeout才能工作

Javascript Angularjs焦点意外地需要异步setTimeout才能工作,javascript,angularjs,Javascript,Angularjs,好的,给我猜个谜语 我有一个按钮,我点击它切换输入的可见性。在改变可见性的scope函数中,我使用javascript设置该输入标记的焦点。我想知道的是,为什么它不工作,除非我把它包装在一个setTimeout $scope.toggle = function() { if ($scope.hideInput) { setTimout(function(){ input.focus(); }, 0); // That's right, zero! } $

好的,给我猜个谜语

我有一个按钮,我点击它切换输入的可见性。在改变可见性的scope函数中,我使用javascript设置该输入标记的焦点。我想知道的是,为什么它不工作,除非我把它包装在一个
setTimeout

$scope.toggle = function() {
  if ($scope.hideInput) {
    setTimout(function(){
      input.focus();
    }, 0);  // That's right, zero!
  }
  $scope.hideInput = !scope.hideInput;
};
下面是一个正在工作的JSFIDLE,它有一个正确设置焦点的按钮和一个不设置焦点的按钮:


可以告诉你原因

首先,使用css
display:none
,无法聚焦元素

因此,在one(breaked)方法中,您可以在元素实际显示之前对其进行聚焦。 因为角度会逐行移动,
$scope.hideInput=!scope.hideInput将触发观察器进行
摘要
-循环。在该循环中,您的输入将设置为
display:block

超时将焦点命令移动到它自己的线程中,
$scope.hideInput=!scope.hideInput
也将触发
摘要。
但是,
digest
非常快,足以在
input.focus()之前显示元素将被执行

这是我的解释,但理解了这一点,确实帮助我解决了一些关于angular计时的奇怪问题

也许用这个


通过变量设置焦点的指令。

听起来很合理。我想知道我是否保证这项工作是决定性的,或者我是否刚刚在代码中引入了竞争条件。