AngularJS - 重置$scope.value不会改变模板中的值(随机行为)



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

我已经做了一些调试。

首先,对我来说,幸运数字不是随机出现在输入框中的。

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激发的输入事件时,该事件由input指令的侦听器函数处理。侦听器函数调用$setViewValue$setViewValue设置$viewValue、$modelValue、模型值并调用$viewChangeListeners(ngChangeDirective只是将处理程序添加到$viewChangeListers)。显示警报,幸运数字设置为空。毕竟,如果luckynumber与之前脏检查中的上一个值不同,则调用$watchhandler和$render。

在我的示例中,如果以前的模型值为"3"或",则调用$render。如果以前的模型值为null,则不调用$render。

为什么$timeout with 0 delay有效:当您调用$timeout with0 delay函数,并将luckynumber更改为null时,它会延迟到事件队列的末尾(浏览器中的所有javascript都在单个线程上执行)$viewChangeListener没有将模型值从7更改为null$摘要结束。然后调用$timeout处理程序。模型值设置为null$调用watchhandler和$render$render将输入值设置为"。

终于有了一个解决方案。使用$watch而不是ng-change:

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

Fiddle。

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

如果您只需放置

$scope.luckynumber = undefined;

在发出警报之前,你没有消除比赛条件,但你确实改变了它,使7确实被正确清除,但有时你会收到两次警报。

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

最新更新