在指令测试中应用与摘要

如果我有一个指令来响应范围中特定属性的状态,并且我想在测试中更改该属性并验证它的响应是否正确,那么哪种方法是进行更改的最佳方式?

这两种模式我都见过:

scope.$apply(function() {
scope.myAttribute = true;
});

还有

scope.myAttribute = true;
scope.$digest();

它们之间有什么区别,哪个更好,为什么?

40777 次浏览

As the documentation itself mentions $digest cycle is peformed any time you do $scope.$apply. As per developer guide on scope

After evaluating the expression, the $apply method performs a $digest. In the $digest phase the scope examines all of the $watch expressions and compares them with the previous value.

And as per the Scope API documentation

Usually you don't call $digest() directly in controllers or in directives. Instead a call to $apply() (typically from within a directives) will force a $digest().

So you should not explicitly call $digest, you calling $apply method would trigger a digest cycle.

scope.$digest() will fire watchers on the current scope, and on all of its children, too. scope.$apply will evaluate passed function and run $rootScope.$digest().

The first one is faster, as it needs to evaluate watchers for current scope and its children. The second one is slower, as it needs to evaluate watchers for$rootScope and all it's child scopes.

When an error occurs in one of the watchers and you use scope.$digest, it's not handled via $exceptionHandler service, so you need to handle exception yourself. scope.$apply uses a try-catch block internally and passes all exceptions to $exceptionHandler.