ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'undefined'

匿名 (未验证) 提交于 2019-12-03 02:52:02

问题:

I know there are a lot of same questions already posted in stackoverflow and tried different solutions to avoid the runtime error but None of them are not working for me.

Component and Html Code

export class TestComponent implements OnInit, AfterContentChecked {     @Input() DataContext: any;     @Input() Position: any;     sampleViewModel: ISampleViewModel = { DataContext: : null, Position: null };     constructor(private validationService: IValidationService, private modalService: NgbModal, private cdRef: ChangeDetectorRef) {     }      ngOnInit() {      }     ngAfterContentChecked() {              debugger;             this.sampleViewModel.DataContext = this.DataContext;             this.sampleViewModel.Position = this.Position;      }   <div class="container-fluid sample-wrapper text-center" [ngClass]="sampleViewModel.DataContext?.Style?.CustomCssClass +' samplewidget-'+ sampleViewModel.Position?.Columns + 'x' + sampleViewModel.Position?.Rows">      //some other html here </div> 

Please Note : This Component is loaded dynamically using DynamicComponentLoader

After My trouble shooting I have identified couple of issues

First of all this child component is loaded dynamically by using DynamicComponentResolver and passing the input values like below

 ngAfterViewInit() {     this.renderWidgetInsideWidgetContainer();    }     renderWidgetInsideWidgetContainer() {     let component = this.storeFactory.getWidgetComponent(this.dataSource.ComponentName);     let componentFactory = this._componentFactoryResolver.resolveComponentFactory(component);     let viewContainerRef = this.widgetHost.viewContainerRef;     viewContainerRef.clear();     let componentRef = viewContainerRef.createComponent(componentFactory);     debugger;     (<IDataBind>componentRef.instance).WidgetDataContext = this.dataSource.DataContext;     (<IDataBind>componentRef.instance).WidgetPosition = this.dataSource.Position;    } 

Even If I changed my child component html like below I am getting this same error.Just add a angular ngclass attribute

<div class="container-fluid ds-iconwidget-wrapper text-center" [ngClass]="Sample">  </div> 

My databinding and everything are working fine.Do I need to do anything on parent component? I already tried all the lifecyle events in child component

回答1:

The ngAfterContentChecked lifecycle hook is triggered when bindings updates for the child components/directives have been already been finished. But you're updating the property that is used as a binding input for the ngClass directive. That is the problem. When Angular runs validation stage it detects that there's a pending update to the properties and throws the error.

To understand the error better, read these two articles:

Think about why you need to change the property in the ngAfterViewInit lifecycle hook. Any other lifecycle that is triggered before ngAfterViewInit/Checked will work, for example ngOnInit or ngDoCheck or ngAfterContentChecked.

So to fix it move renderWidgetInsideWidgetContainer to the ngOnInit() lifecycle hook.



回答2:

you have to tell angular that you updated the content after ngAfterContentChecked you can import ChangeDetectorRef from @angular/core and call detectChanges

import {ChangeDetectorRef } from '@angular/core';  constructor( private cdref: ChangeDetectorRef ) {}    ngAfterContentChecked() {  debugger; this.sampleViewModel.DataContext = this.DataContext; this.sampleViewModel.Position = this.Position; this.cdref.detectChanges();      } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!