98

If I have a directive that responds to the status of a particular attribute on the scope, and I want to change that attribute in my test and verify that it responds correctly, which is the best way of doing that change?

I've seen both these patterns:

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

and

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

What is the difference between them, and which is better and why?

4

2 回答 2

207

scope.$digest()将在当前范围及其所有子范围内触发观察者。scope.$apply将评估传递的函数并运行$rootScope.$digest()

第一个更快,因为它需要评估当前范围及其子范围的观察者。第二个速度较慢,因为它需要评估观察者$rootScope及其所有子作用域。

当其中一个观察者发生错误并且您使用scope.$digest时,它不会通过$exceptionHandler服务处理,因此您需要自己处理异常。scope.$apply在内部使用一个try-catch块并将所有异常传递给$exceptionHandler.

于 2013-09-09T12:13:30.737 回答
12

正如文档本身提到的那样,您随时都会执行 $digest 循环$scope.$apply。根据范围的开发人员指南

计算表达式后,$apply 方法执行 $digest。在 $digest 阶段,作用域检查所有 $watch 表达式并将它们与之前的值进行比较。

并根据 Scope API文档

通常你不会在控制器或指令中直接调用 $digest() 。相反,对 $apply() 的调用(通常在指令中)将强制执行 $digest()。

所以你不应该显式调用$digest,你调用$apply方法会触发一个摘要循环。

于 2013-09-09T12:09:34.873 回答