如何调试“检查后表达式更改”错误?

时间:2017-10-25 12:48:25

标签: javascript angular typescript debugging angular2-changedetection

这是一个臭名昭着的错误,它在开发人员之间有一个非常“跟随”,但是它也被认为是非常棘手的调试。像这样的日志

PersonalSituationComponent.html:3 ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'true'. Current value: 'false'.
at viewDebugError (core.es5.js:8434) [angular]
at expressionChangedAfterItHasBeenCheckedError (core.es5.js:8412) [angular]
at checkBindingNoChanges (core.es5.js:8576) [angular]
at checkNoChangesNodeInline (core.es5.js:12455) [angular]
at checkNoChangesNode (core.es5.js:12429) [angular]
at debugCheckNoChangesNode (core.es5.js:13209) [angular]
at debugCheckRenderNodeFn (core.es5.js:13149) [angular]
at Object.eval [as updateRenderer] (PersonalSituationComponent.html:3) [angular]
at Object.debugUpdateRenderer [as updateRenderer] (core.es5.js:13131) [angular]
at checkNoChangesView (core.es5.js:12251) [angular]
at callViewAction (core.es5.js:12618) [angular]
at execEmbeddedViewsAction (core.es5.js:12596) [angular]
at checkNoChangesView (core.es5.js:12250) [angular]
at callViewAction (core.es5.js:12618) [angular]

并没有多大帮助。如果在html的第3行占用很多,那么该行中没有布尔值,但 是一个组件的开始标记,它在其他地方确实有一些(.ts)和.html分别)。

如何在不使用硬编码值替换所有布尔值并分别检查每个布尔值的情况下,如何调试此类错误? (当你打字时,我会这样做。)

3 个答案:

答案 0 :(得分:2)

有很多帖子显示了如何弄清楚' ExpressionChangedAfterItHasBeenCheckedError'但是,错误是一个好的起点是阅读此内容以了解此错误的含义:https://blog.angularindepth.com/everything-you-need-to-know-about-the-expressionchangedafterithasbeencheckederror-error-e3fd9ce7dbb4

但是,如果你只是想要一种懒惰的方法来解决这个问题,那就开始评论一下,找出造成这个错误的罪魁祸首。一旦你隔离了导致的行,然后可能会再次发布"当我有这条线时,我会得到这个错误"我们或许可以帮助你更好。

如果您仍然不想这样做,那么一旦您找到有问题的代码,那么只需尝试社区通常建议的一些事情:

  • 用setTimeout包装你的代码(这只是一个黑客攻击)
  • 运行变更检测检测,如@Milo的另一个答案所述
  • 确保正确销毁子元素

此错误有很多帖子,如果您付出更多努力并让我们更好地了解您的代码,那么我们可能会帮助您做得更好。

祝你好运! :)

答案 1 :(得分:0)

您可以对组件中怀疑的变量值更改运行手动更改检测,直到错误得到解决。一旦找到它,您就可以决定是重新设计实现还是只进行手动更改检测。

import { ChangeDetectorRef } from '@angular/core';

constructor(private _cdRef: ChangeDetectorRef) { }

this._cdRef.detectChanges();

答案 2 :(得分:0)

你必须逐字调试,因为目前angular不提供任何有意义的细节,除了值。

如果你在所有错误上设置调试器选项中断,你将能够遍历堆栈(有点明显吗?)并查看发生问题的组件名称。