【问题标题】:Angular $watch function after change variable更改变量后的角度 $watch 函数
【发布时间】:2016-06-07 00:00:19
【问题描述】:

我正在尝试构建一个延迟消息框。我观察到 apply 在应用程序启动时被调用,如 API 文档中所述。但是当观察值改变时,它不会被调用。 MessageCtrl 是内部控制器。为什么在更改 message var 后不调用 watch

angular.module('myApp',[]).controller('MessageCtrl', function($scope) {

  $scope.getMessage = function() {
    setTimeout(function() {
      $scope.$parent.message = {text : ""}; 
      $scope.$apply(function() {        
        console.log('message:' + $scope.$parent.message.text);
      });
    }, 2000);
  }
  $scope.getMessage();    
})
.controller('MainCtrl',function($scope){
  $scope.message={text:"oi"};
  $scope.$watch("message", function(newValue, oldValue){
      console.log("watch " + $scope.message.text);
  });
});

内部控制器 MessageCtrl 将获取文本消息并显示 2 秒。

<body ng-app="myApp" ng-controller="MainCtrl">
  <div ng-controller="MessageCtrl">
    Message:{{message.text}} 
  </div>
</body>

【问题讨论】:

    标签: angularjs watch


    【解决方案1】:

    据我所知,您的代码确实有效。但是,您错误地使用了$apply$apply 让您通知 Angular 您正在更改常规方法之外的状态,因此应该重新评估绑定等。所以您应该使用

    $scope.$apply(function() { $scope.$parent.message = {text: 'new message'}; });
    

    angular.module('myApp', []).controller('MessageCtrl', function($scope) {
    
        $scope.getMessage = function() {
          setTimeout(function() {
            $scope.$apply(function() {
              $scope.$parent.message = {
                text: "new message"
              };
              console.log('message:' + $scope.$parent.message.text);
            });
          }, 2000);
        }
        $scope.getMessage();
      })
      .controller('MainCtrl', function($scope) {
        $scope.message = {
          text: "oi"
        };
        $scope.$watch("message", function(newValue, oldValue) {
          console.log("watch " + $scope.message.text);
        });
      });
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    
    <div ng-app="myApp" ng-controller="MainCtrl">
      <div ng-controller="MessageCtrl">
        Message:{{message.text}}
      </div>
    </div>

    需要注意的是,您应该真正使用 angular $timeout 服务,它允许您在应用程序中设置超时,但您不必处理调用 $apply。

    angular.module('myApp', []).controller('MessageCtrl', function($scope, $timeout) {
    
        $scope.getMessage = function() {
          $timeout(function() {
            $scope.$parent.message = {
              text: "new message"
            };
            console.log('message:' + $scope.$parent.message.text);
          }, 2000);
        }
        $scope.getMessage();
      })
      .controller('MainCtrl', function($scope) {
        $scope.message = {
          text: "oi"
        };
        $scope.$watch("message", function(newValue, oldValue) {
          console.log("watch " + $scope.message.text);
        });
      });
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    
    <div ng-app="myApp" ng-controller="MainCtrl">
      <div ng-controller="MessageCtrl">
        Message:{{message.text}}
      </div>
    </div>

    【讨论】:

      【解决方案2】:

      您需要使用$scope.apply 方法,因为setTimeout 函数不是角度原生函数:

          setTimeout(function() { 
      $scope.apply({
      $scope.$parent.message = {text : ""}; $scope.$apply(function() { console.log('message:' + $scope.$parent.message.text); });}) ;}, 2000);
      

      或者你也可以像这样在角度使用$timeout inbuilt-service:

      angular.module('myApp',[]).controller('MessageCtrl', function($scope, , $timeout) { $scope.getMessage = function() { $, $timeout(function() { $scope.$parent.message = {text : ""}; $scope.$apply(function() { console.log('message:' + $scope.$parent.message.text); }); }, 2000); } $scope.getMessage(); })
      

      【讨论】:

        【解决方案3】:

        使用$timeout 代替$apply 执行$apply implicity

        angular.module('myApp',[]).controller('MessageCtrl', function($scope, $timeout) {
        $scope.getMessage = function() {
           $timeout(function() {
              $scope.$parent.message = {text : ""}; 
              $scope.$apply(function() {        
                console.log('message:' + $scope.$parent.message.text);
              });
            }, 2000);
          }
          $scope.getMessage();    
        })
        

        【讨论】:

          猜你喜欢
          • 2015-12-14
          • 1970-01-01
          • 2016-08-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多