指令测试中的 $apply 与 $digest
Posted
技术标签:
【中文标题】指令测试中的 $apply 与 $digest【英文标题】:$apply vs $digest in directive testing 【发布时间】:2013-09-12 21:55:07 【问题描述】:如果我有一个指令响应范围上特定属性的状态,并且我想在我的测试中更改该属性并验证它是否正确响应,那么执行该更改的最佳方法是什么?
这两种模式我都见过:
scope.$apply(function()
scope.myAttribute = true;
);
和
scope.myAttribute = true;
scope.$digest();
它们之间有什么区别,哪个更好,为什么?
【问题讨论】:
【参考方案1】:scope.$digest()
将在当前作用域及其所有子作用域上触发观察者。 scope.$apply
将评估传递的函数并运行 $rootScope.$digest()
。
第一个更快,因为它需要评估当前范围及其子范围的观察者。第二个比较慢,因为它需要评估$rootScope
及其所有子作用域的观察者。
当其中一个观察者发生错误并且您使用scope.$digest
时,它不会通过$exceptionHandler
服务处理,因此您需要自己处理异常。 scope.$apply
在内部使用 try-catch
块并将所有异常传递给 $exceptionHandler
。
【讨论】:
$digest
也会被调用到作用域的孩子上吗?
这可能会产生误导。 $digest
不仅会在当前范围内触发观察者,还会在其所有子级上触发。
@tasseKATT,我想我已经理解了您的评论所暗示的内容。【参考方案2】:
正如文档本身所提到的,$digest 循环在您执行$scope.$apply
的任何时候都会执行。根据scope的开发者指南@
计算表达式后,$apply 方法执行 $digest。 在 $digest 阶段,作用域检查所有 $watch 表达式 并将它们与之前的值进行比较。
根据 Scope API documentation
通常你不会直接在控制器中调用 $digest() 或 指令。而是调用 $apply() (通常来自 指令)将强制执行 $digest()。
所以你不应该显式调用$digest
,你调用$apply
方法会触发一个摘要循环。
【讨论】:
这是不正确的,因为对于大多数只需要评估当前范围及其子范围的情况,摘要就足够了。确实 $scope.$apply 在内部调用 $digest 但记住它最终会调用 $rootScope.$digest() 并因此非常重以上是关于指令测试中的 $apply 与 $digest的主要内容,如果未能解决你的问题,请参考以下文章
理解Angular中的$apply()以及$digest()
理解Angular中的$apply()以及$digest()
理解Angular中的$apply()以及$digest()
理解Angular中的$apply()以及$digest()