$ scope.$ watch不会触发每次更改

Sah*_*bin 20 javascript angularjs

我正在使用angularJS 1.4.8,昨天我注意到$ scope.$ watch不会触发每次导致我的应用程序错误的更改.

有没有办法迫使它立即对每一个变化起作用?就像在这段代码中一样,在消息的每一次更改中,我希望watch中的函数触发:

(function(){

  angular.module('myApp', [])
  .controller('myAppController', myAppController)

  function myAppController($scope){
    console.log('controller loading !');
    $scope.message = 'message1';

    $scope.$watch('message', function(newMessage){
      console.log('newMessage', newMessage)
    });

    function changeMessage(){
      $scope.message='hi';
      $scope.message='hi12';
    }

    changeMessage(); 
  }

})();
Run Code Online (Sandbox Code Playgroud)

控制台将打印:

controller loading !
newMessage hi22
Run Code Online (Sandbox Code Playgroud)

plunker链接https://plnkr.co/edit/SA1AcIVwr04uIUQFixAO?p=preview

编辑:我真的想知道是否有任何其他方法,而不是包装更改与超时和使用范围适用,在我的原始代码iv'e多个地方,我改变范围属性,我想避免使用这每一个更改.

Mar*_*und 11

发生这种情况是因为只有在"消化循环之间"更改值时才会触发监视.

您的函数正在更改同一函数中作用域上的消息值.这将在同一个摘要循环中执行.当角度移动到下一个循环时,它将只看到最后一个更改的值,在您的情况下hi22.

这是一篇很好的文章,可以清楚地表达这种行为


Aji*_*ote 5

更新你的changeMes​​sage函数,以便它使用$ scope.$ apply函数,它将确保反映你的更改,并且angular知道你对变量的更改.

changeMessage() {
   setTimeout(function () {
        $scope.$apply(function () {
          $scope.message = "Timeout called!";
        });
    }, 2000);
}
Run Code Online (Sandbox Code Playgroud)

  • 为什么需要将`setTimeout`和$ apply`配合使用?你可以在没有$ apply的情况下使用$ timeout来做同样的事情,反之亦然。`$ apply`正在运行`$ digest`和`$ timeout`最后做同样的事情。您可以在这里阅读有关内容:https://www.codingeek.com/angularjs/angular-js-apply-timeout-digest-evalasync/ (2认同)
  • 这实际上不是将更改应用于`$ scope`的好方法.更好的是使用`$ timeout`函数中的构建. (2认同)