【问题标题】:AngularJS - reset of $scope.value doesn't change value in template (random behavior) [closed]AngularJS - $scope.value 的重置不会改变模板中的值(随机行为)[关闭]
【发布时间】:2012-08-24 00:05:25
【问题描述】:

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

【问题讨论】:

  • 这是个好问题。你在这里进入了一种竞争状态,这就是它没有得到正确解决的原因。有兴趣找到解决此问题的正确方法。
  • 使用$timeout service怎么样? jsfiddle.net/2NJ7y/10 但我一直不明白为什么它的延迟为 0。
  • @Artem:这不是很好的解决方法,但可以。但我仍在等待最终的解决方案。 :-) 谢谢。
  • @Artem,Misko 的评论表明 $timeout(以前称为 $defer)在浏览器呈现后运行:github.com/angular/angular.js/issues/734#issuecomment-3657272 我想这有助于避免控制器函数之间的竞争条件尝试更改值,浏览器呈现“7”......也许??
  • @Mark 谢谢。我还找到了good explanations about setTimeout(fn, 0)

标签: angularjs


【解决方案1】:

如果你简单地说

$scope.luckynumber = undefined;

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

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

【讨论】:

    【解决方案2】:

    我已经做了一些调试。

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

    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 仅当先前的模型值为 null 时才留在输入字段中。

    会发生什么:当您输入由listener functioninput directive 处理的7 个触发输入事件时。监听函数调用$setViewValue。 $setViewValue 设置 $viewValue、$modelValue、模型值并调用 $viewChangeListeners(ngChangeDirective simply adds handler 到 $viewChangeListeners)。显示警报,luckynumber 设置为空。毕竟,如果luckynumber 与之前脏检查的值不同,则调用$watch handler$render

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

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

    【讨论】:

      【解决方案3】:

      终于找到了解决方案。使用 $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 answer 让我想到尝试解决这个问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-31
        • 2018-09-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多