在$ rootScope上运行$ apply与任何其他范围

时间:2013-07-25 21:16:19

标签: angularjs angularjs-scope

$apply函数可以在任何范围内运行,包括$rootScope

如果我在本地范围内运行它或者我在$rootScope上运行它会有什么不同吗?

我在问,因为我想创建一个帮助函数来包装$apply中的给定函数。要做到这一点,我总是需要传入一个范围,这是A)烦人和B)不容易,因为我不一定有本地范围。

我希望$apply上的助手函数调用$rootScope总是如此,但如果这样做有风险,请不要这样做。

4 个答案:

答案 0 :(得分:46)

在任何范围内运行$apply始终会生成$rootscope.$digest。唯一可能产生影响的情况是,当您将表达式作为$apply的参数提供时。表达式将在当前范围内进行评估(与$ rootScope相比),但之后$rootscope.$digest 总是被调用。

源代码非常清晰:rootScope.js

底线: 如果您在没有参数的情况下调用$apply,则没有任何区别。

答案 1 :(得分:15)

当我需要在将由不同控制器使用的服务中调用$apply时,通常会在$rootScope上而不是$scope上运行$apply的另一个原因因此范围不同。
在这种情况下,我更喜欢将$rootScope注入服务并在其上调用$ apply,而不必担心将来会使用该服务的范围。

答案 2 :(得分:11)

在任何给定范围内运行$ digest / $ apply将使用深度优先遍历访问所有其他范围:

https://github.com/angular/angular.js/blob/3967f5f7d6c8aa7b41a5352b12f457e2fbaa251a/src/ng/rootScope.js#L550-L558

这意味着唯一的区别是$ digest将从它所调用的任何$范围开始

答案 3 :(得分:0)

/* What happens with $apply */ 
angular.module('myApp',[]).controller('MessageController', function($scope) {
    
      $scope.getMessage = function() {
        setTimeout(function() {
          $scope.$apply(function() {
            //wrapped this within $apply
            $scope.message = 'Fetched after 3 seconds'; 
            console.log('message:' + $scope.message);
          });
        }, 2000);
      }
      
      $scope.getMessage();
    
    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<body ng-app="myApp">
      <div ng-controller="MessageController">
        Delayed Message: {{message}}
      </div>  
    </body>