ExpressionChangedAfterItHasBeenCheckedError和context Error Angular 4

时间:2017-07-19 14:15:07

标签: angular

遇到此错误且无法从控制台调试:

ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'undefined'. Current value: 'Main Bike Trails'.
    at viewDebugError (core.es5.js:8418)
    at expressionChangedAfterItHasBeenCheckedError (core.es5.js:8396)
    at checkBindingNoChanges (core.es5.js:8560)
    at checkNoChangesNodeInline (core.es5.js:12421)
    at checkNoChangesNode (core.es5.js:12395)
    at debugCheckNoChangesNode (core.es5.js:13172)
    at debugCheckRenderNodeFn (core.es5.js:13112)
    at Object.eval [as updateRenderer] (MapComponent.html:12)
    at Object.debugUpdateRenderer [as updateRenderer] (core.es5.js:13094)
    at checkNoChangesView (core.es5.js:12217)## 

从以下给定方法生成错误。它运作不正常。

ngAfterViewInit() {
    this._mapService.plotActivity(+this._route.snapshot.params['id']);
    this.activityName = this.activity.name;
    this.activityComments = this.activity.comments;
    this.activityDistance = this.activity.distance;
    this.activityDate = this.activity.date;
    this.gpx = this.activity.gpxData;
}

2 个答案:

答案 0 :(得分:0)

您是否尝试使用ngAfterContentInit()方法移动更改?看看这个页面有很好的解释:

https://angular.io/guide/lifecycle-hooks#aftercontent

答案 1 :(得分:0)

我看到许多有角度的开发人员在得知这个错误时不知道究竟是什么原因,所以让我先花点时间解释一下这个问题然后我会解释什么是可能的解决方案。

角度变化检测的工作原理

没有关于角度变化检测机制如何工作的基本概念是开发人员遇到这个问题的主要原因所以请尽快给我几行解释。

我们可以将angular应用程序视为根组件之后的组件树,其下面有许多子组件,因此当组件中的某些内容发生更改时,angular将评估从根组件到所有子组件的表达式。

Angular快速评估根组件的所有表达式并更新dom,然后最终将所有变量值保存在名为oldValues的对象中,例如假设您在name中有john属性根组件及其值从peter更改为name,然后一旦角度完成更新dom,它会记住属性peter的新值为oldValues,它将开始处理下一个子组件。

这里要注意的重要一点是,一旦角度完成了单个组件的过程,它就不会期望该组件的任何属性会在同一个摘要圈内发生变化。

在什么时候出现此错误

最后,当一个摘要圈完成时,它将运行另一个循环来验证所有组件中的所有值(此循环仅在开发模式下运行),所以这里发生的是角度将看到它&#39 ; s oldValues每个组件的对象,并验证组件中的现有值是否与ExpressionChangedAfterItHasBeenCheckedError对象中的一个相同,但如果它们不相同则则会抛出{{1} }

解决方案

一旦特定组件按角度完成处理,您不应该尝试更改父组件中附加到dom的属性。 如果您仍然需要这样做 - 尽管不建议使用角度完成当前循环,然后让角度在下一个循环中通过执行以下操作来处理您的更改

setTimeout(()=>{
        /* your code goes here */
});