简体   繁体   English

ExpressionChangedAfterItHasBeenCheckedError和上下文错误Angular 4

[英]ExpressionChangedAfterItHasBeenCheckedError and context Error Angular 4

Facing this error and unable to debug from the console : 遇到此错误,无法从控制台进行调试:

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)## 

Error generated from the given method below. 从下面的给定方法生成的错误。 It is not working fine. 它工作不正常。

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;
}

Have you try to move your changes in ngAfterContentInit() method? 您是否尝试过在ngAfterContentInit()方法中进行更改? Look at this page is well explained : 看看这个页面是很好的解释:

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

I see many angular developers are getting this error not knowing what is the real reason, so let me take some time to explain the problem first and then i'll explain what is the possible solution. 我看到许多棱角分明的开发人员在不知道真正原因是什么的情况下出现了此错误,因此让我先花一些时间来解释问题,然后再解释什么是可能的解决方案。

How angular change detection works 角度变化检测如何工作

Not having a basic idea of how angular change detection mechanism works is the main reason why developers get into this problem so give me few lines to explain it very shortly. 对于开发人员遇到此问题的主要原因,尚不了解角度变化检测机制的工作原理,因此请给我几句简短的解释。

we can consider angular application as a tree of components after the root component there are many child components beneath it, so when something change in a component angular will evaluate the expressions from root component to all child components. 我们可以将角度应用视为组件树,在根组件之后有许多子组件,因此,当组件角度发生某些变化时,它将评估从根组件到所有子组件的表达式。

Angular quickly evaluate all expressions for the root component and update the dom then finally it will keep all the variable values in a object called oldValues , for example lets say you have a name attribute in the root component and its value changed from john to peter then once angular finished updating the dom it remembers that new value of attribute name is peter and it will start processing the next child component. Angular快速评估根组件的所有表达式并更新dom,然后最终它将所有变量值保留在名为oldValues的对象中,例如,假设您在根组件中具有name属性,并且其值从john更改为peter然后一旦角度更新完dom,它就会记住属性name新值是peter ,它将开始处理下一个子组件。

Important thing to note here is that once angular finished the process for single component it does not expect that any of the attributes of that component will change within the same digest circle. 这里要注意的重要一点是,一旦完成了单个零件的角操作,它就不会期望该零件的任何属性在同一摘要圆内发生变化。

At what point you get this error 在什么时候出现此错误

Finally when a single digest circle is done it will run another loop to verify all the values in all the components ( this loop will only run in development mode only ), so what happens here is that angular will look at it's oldValues object for each and every component and verify that existing value in the component are the same as the once in the oldValues object but in case if they are not then angular will throw ExpressionChangedAfterItHasBeenCheckedError 最后,当完成一个摘要循环时,它将运行另一个循环以验证所有组件中的所有值(该循环仅在开发模式下运行),因此这里发生的是,角度将针对每个对象查看其oldValues对象。每个组件并验证组件中的现有值是否与oldValues对象中的值相同,但如果它们不相等,则角度将抛出ExpressionChangedAfterItHasBeenCheckedError

Solution

You should not be trying to change the attributes that are attached to dom in the parent component once that particular component has finished processing by angular. 一旦特定组件完成了按角度的处理,就不应尝试更改附加到父组件中dom的属性。 if you still need to do so even-though it is not recommended then let angular finish the current cycle and then allow angular to process your changes in the next cycle by doing following 如果您仍然需要这样做,尽管不建议这样做,那么让angular完成当前循环,然后通过以下操作允许angular在下一个循环中处理您的更改

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM