从摘要周期中移除和恢复 Scope

12

有没有一种方法可以从$scope的$digest循环中移除作用域?换句话说,可以暂停/恢复一个作用域的$digest循环吗?

在我的情况下,所有页面都已经加载完毕,但并不是所有页面都可见。所以我想暂停那些不可见的页面以避免无用的处理。我不想使用ng-view + $route,我不需要深度链接。

我看到了这个线程,并找到了这个示例。它可能做到了这一点,但它相当具有侵入性,并且不太适合更新框架。

是否有其他解决方案,比如$scope.suspend()scope.resume()?或者更少侵入性的解决方案(从框架角度来看)?我目前在考虑$destroy$compile周期。

2个回答

12

我曾遇到同样的问题,并找到了一个有趣的解决方案,它不会(太多地)干扰AngularJS。将以下内容添加到您想要禁用的作用域中:

var watchers;

scope.$on('suspend', function () {
  watchers = scope.$$watchers;
  scope.$$watchers = [];
});

scope.$on('resume', function () {
  scope.$$watchers = watchers;
  watchers = null;
});

然后,你可以使用以下代码禁用一个作用域及其子作用域:scope.$broadcast('suspend'),并使用scope.$broadcast('resume')重新启用。


不错的技巧。这肯定会奏效,尽管我不太喜欢hack,因为它会使升级版本更加困难。无论如何,如果有人使用这种方法,最好也覆盖$scope.$watch,因为在禁用时可能会添加新的观察者。 - Caio Cunha
我刚刚发布了一篇关于这个技术的简短文章:https://coderwall.com/p/d_aisq - Laurent Perrin
这让我避免了一个非常棘手的问题——应用程序中有时不可见的性能低下的表格。长期的解决方案是对可排序表格进行分页处理并实现无限滚动……但是这样会拖延我们专注于当前更重要的功能,所以采用了这种解决办法。好极了,技术负债! - FlavorScape

3

目前该框架没有暂停/恢复作用域中的脏检查方法。尽管如此,有几种技术可用于限制在脏检查循环中执行的监视器数量。

首先,如果屏幕的某些部分无论如何都被隐藏,您可以使用ng-switch系列指令,从而完全从DOM中删除不可见的部分。

其次,如果您的指令通过$apply触发了脏检查循环,并且希望将监视器重新评估限制为子作用域,则可以调用$digest而不是$apply

然后,是的,可以像您链接到的讨论中描述的那样销毁和重新创建作用域。但是,如果您已经隐藏了DOM的某些部分,那么使用ng-switch可能是更好的选择。


使用 ng-switch 对于这种情况确实是一个可考虑的选项。但是你不认为有人使用非 Angular 代码希望在不让 ng-switch 控制操作的情况下暂停 DOM 的某个部分更新是合理的吗?我们当然可以模仿 ng-switch 的行为,但似乎这是大型混合项目性能调优的关键特性。此外,也许有一种方法只运行 ng-bind 观察,防止其它观察运行。不知道...请分享您的想法。 - Caio Cunha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接