Javascript 取消根作用域摘要调用的绑定

Javascript 取消根作用域摘要调用的绑定,javascript,angularjs,digest,Javascript,Angularjs,Digest,如果我立即连续调用$scope.$apply()十次,我假定将发生十次根范围摘要 我们是否可以说,如果对$scope.$apply()的调用已取消抖动,因此后续调用始终已完成,则应用程序的最终状态将与取消抖动未生效时相同 考虑到前一个摘要刚刚完成,我们可以谈谈连续根范围摘要的持续时间吗 编辑: 我想澄清我问题的目的 假设我有一个控制器MyController,为指令MyDirective的每个实例实例化一个实例 这些控制器实例侦听事件my event,并在每次引发my event时触发根作用域摘

如果我立即连续调用
$scope.$apply()
十次,我假定将发生十次根范围摘要

我们是否可以说,如果对
$scope.$apply()
的调用已取消抖动,因此后续调用始终已完成,则应用程序的最终状态将与取消抖动未生效时相同

考虑到前一个摘要刚刚完成,我们可以谈谈连续根范围摘要的持续时间吗

编辑:

我想澄清我问题的目的

假设我有一个控制器
MyController
,为指令
MyDirective
的每个实例实例化一个实例

这些控制器实例侦听事件
my event
,并在每次引发
my event
时触发根作用域摘要

MyDirective
的十个实例通过
ng repeat
呈现到UI

另一个组件引发一个事件
my event
。然后,十个MyController实例中的每一个都会触发根范围摘要

如果我们把这种状态的合理性放在一边,那么我的问题是:如果我对MyController所做的根范围摘要尝试进行去抖动,并确保始终调用后续尝试,那么程序的正确性是否得到维护

var service = require('my-service');

function MyController($scope) {
  this._$scope = $scope;
  myService.on('my-event', this.triggerRootScopeDigest.bind(this));
}

MyController.prototype.triggerRootScopeDigest = function() {
  this._$scope.apply();
}

编辑后的问题仍然指向
$applyAsync
$evalAsync
作为您的解决方案

下面是一个比较
$apply()
$applyAsync()
的小提琴示例:

您会注意到,通过
ngRepeat
添加了10个项目,每个项目都观察
doApply
事件和
doApplyAsync
事件,以触发相应的功能

当您单击广播
doApply
的按钮时,它会触发10个
$digest
调用,每个调用都执行指令(在本例中,作为简单的
console.log

然而,
doApplyAsync
广播会使所有10条指令在一个
$digest
中完成它们的工作

当然,取消公告的回调也会起作用。您可以向每个指令传递对附加到父控制器作用域的取消公告函数的引用。如果该去盎司功能工作正常,且有足够长的去盎司时间,则只应用一次。在某些情况下,这是首选,但原始问题感觉很简单(假设触发
$digest
是事件的主要目标),用
$apply
替换
$applyAsync
(或
$evalassync
,取决于语义)似乎更合适


编辑:虽然结果完全相同,但此小提琴更准确,因为它直接触发元素上的真实DOM事件:

“如果我调用$scope.$apply()十次”。你根本不应该调用它。如果您真的需要(例如,在自定义指令事件、套接字等),那么首先考虑删除事件处理程序。听起来,虽然我可能是错的,但您不必需要去抖动,而是简单地对摘要循环请求进行批量处理。除非这些都是基于用户交互的,否则通常情况下,批处理到一个周期中效果很好。更简单的方法是,将调用
$apply
的任务包装在以下任务之一中:
applyAsync
evalAsync
(如果您不介意所有任务都在当前
$digest
周期中运行,如果有),或者如果您希望它们都落在下一个周期中,则包装在
$timeout
中。@DRobinson,如果您的意思是“批处理”,将多个根作用域摘要请求分组为一个,然后是的,这就是我所说的。您指出存在惯用的“批处理”“使用
$timeout
的机制?@dfsq根据您的评论,如果在AngularJS之外触发状态更改,那么还有什么替代方案?@Ben ahh出于某种原因,我脑子里想,
$timeout
是批处理的。事实并非如此。不过,我建议的另外两个也可以: