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

Dom*_*omi 10 javascript angularjs angularjs-ng-repeat angularjs-ng-include

我目前正在处理一些带有延迟加载内容+控制器的代码.我的代码基本上就像这个小提琴一样.但是,出于某种原因,我的版本不起作用,而只要角度尝试更新它的视图,我就会获得无限的摘要周期.

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

<div class="container" ng-repeat="pageName in pageNames">
  <div ng-include="pageName"></div>
</div>
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

更新:

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

Cha*_*son 13

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

angular.js > src> ng> rootScope.js

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

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

对此的一个简单测试是更改您的服务器以返回任何未找到的资源的空404.每当有人提到"无限循环"和任何类型的资产加载操作时,我总是推荐这个:ui-router,ngRoute,ngInclude等.

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