11

看看http://jsfiddle.net/2NJ7y/3/上的例子(AngularJS 1.0.1 的版本)。有一个简单的应用程序,正在等待输入幸运数字。如果数字等于 7,我将幸运数字重置为空。如果我多次输入数字 7,有时/随机幸运数字会留在输入字段中。为什么?这种行为如何解决?谢谢。

4

3 回答 3

6

我做了一些调试。

首先对我来说幸运数字不是随机地留在输入字段中。

enter 3 (model==3, input==3)=>enter 7 (alert, model==null, input="")

=> enter 3 (model==3, input==3)=>remove 3 (model=="", input=="")

=>enter 7 (alert, model==null, input="")

=>enter 7 (alert, model==null, input="7")

7 仅当先前的模型值为空时才留在输入字段中。

会发生什么:当您输入 7 触发的输入事件时,该事件由输入指令的侦听函数处理。侦听器函数调用$setViewValue。$setViewValue 设置 $viewValue、$modelValue、模型值并调用 $viewChangeListeners(ngChangeDirective只是将处理程序添加到 $viewChangeListeners)。显示警报,luckynumber 设置为空。毕竟,如果luckynumber 与先前脏检查的先前值不同,则调用$watch 处理程序$render

在我的示例中,如果先前的模型值为“3”或“”,则调用 $render。如果之前的模型值为 null,则不会调用 $render。

为什么具有 0 延迟的 $timeout 有效:当您调用具有 0 延迟的 $timeout 函数并将 luckynumber 更改为 null 时,会在事件队列的末尾推迟(浏览器中的所有 javascript 在单个线程上执行)。$viewChangeListener 不会将模型值从 7 更改为 null。$digest 完成。然后调用 $timeout 处理程序。模型值设置为空。$watch 处理程序和 $render 被调用。$render 将输入值设置为“”。

于 2012-09-08T14:02:45.067 回答
3

终于有办法了。使用 $watch 而不是 ng-change:

$scope.$watch('luckynumber', function() {
    if ($scope.luckynumber == 7) {
        alert('The lucky number mustn\'t be equal 7.');
        $scope.luckynumber = null;
    }
})

小提琴

@Valentyn 的另一个SO 回答让我想到尝试解决这个问题。

于 2013-01-20T00:53:06.843 回答
1

如果你简单地说

$scope.luckynumber = undefined;

在警报之前,您并没有消除竞争条件,但您确实更改了它,以便正确清除 7,但有时您会收到两次警报。

如果警报代码被幂等的东西代替,比如改变 DOM 以显示错误,那么这个问题就不重要了。

于 2012-09-07T16:38:53.983 回答