调试Angular摘要周期:如何找到无限循环的原因?

时间:2014-05-21 09:34:23

标签: javascript angularjs angularjs-ng-repeat angularjs-ng-include

我目前正在处理一些带有延迟加载内容+控制器的代码。我的代码基本上像this fiddle一样工作。但是,出于某种原因,我的版本不起作用,而只要角度尝试更新它的视图,我就会得到an infinite digest cycle

当我从这个简单的重复声明中删除ng-include时,问题就消失了:

<div class="container" ng-repeat="pageName in pageNames">
  <div ng-include="pageName"></div>
</div>

最奇怪的部分:即使exact same error从未分配给范围,也会出现pageNames。两个范围(外部和内部控制器的范围 - 我每个都有)可以完全为空(我用Batarang检查 - 我只有两个空的范围),我仍然得到错误。

我的代码有点过于牵连,有太多其他依赖项,所以在这里发布是没有意义的。它最纯粹的版本是上面的小提琴。我无法找到两者之间的逻辑差异。当我用Batarang检查我的示波器时,我也没有看到任何可疑的东西:

  • 我没有在我的范围内使用函数
  • 我没有使用$watch
  • 我没有使用ng-model

我得出的结论是,我没有明确地改变任何东西,所以它必须是有角度的东西。

我可以以某种方式让Angular或Batarang告诉我在摘要迭代后哪些范围变量已经改变,所以我可以识别导致无限循环的罪魁祸首吗?

更新

我终于发现history.pushState混淆了一切。我现在正在研究替代方案,例如$location服务。不过,我仍然想知道如何调试这类问题。任何提示?

1 个答案:

答案 0 :(得分:13)

没有直接的方法可以获得每个摘要中已更改的范围变量列表,但是如果你&#39,修改Angular的源(暂时)非常简单;处于紧急调试状态。 $ digest代码在这里:

angular.js > src > ng > rootScope.js

如果查看此方法,您将看到对watchLog数组的引用。 AngularJS使用它来报告有用的错误消息,当它检测到像您一样的循环时。您可以在此处轻松添加一些console.log项,或者维护您自己可以稍后记录的数组或使用调试器进行检查。您还可以在此处设置断点以查看正在发生的情况。

我不清楚为什么history.pushState()会与此有关,因为您的原始问题并未涉及$ location,history或相关函数的使用。但是请注意,当路径不是您期望的时候,ngInclude创建无限循环是一个非常常见的问题。大量服务器端(例如NodeJS)项目被配置为在找不到资源时返回主页/索引页面,因为它们假设前端路由正在进行中。这实际上是一个很大的问题,因为你最终将主页嵌入主页,然后嵌入另一个副本,等等。我看到这种问题大约每周一次在S / O上发布。

对此的一个简单测试是更改您的服务器以返回任何未找到的资源的空404。每当有人提到&#34;无限循环时,我总是建议这样做。以及任何类型的资产加载操作:ui-router,ngRoute,ngInclude等。

在路径中使用相对URL时,这种情况尤为常见。