ExpressionChangedAfterItHasBeenCheckedError: 表达式在被检查之后已经发生了变化。先前的值是:'undefined'。

145

我知道在stack-overflow上已经有很多相同的问题,并尝试了不同的解决方案来避免运行时错误,但是没有一个适用于我。

错误

组件和HTML代码

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>
请注意:该组件是使用DynamicComponentLoader动态加载的。
在我解决问题后,我已经确定了几个问题。
首先,通过使用DynamicComponentResolver动态加载该子组件,并传递如下输入值。
 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;

  }

即使我将子组件的HTML更改为以下内容,我仍会收到相同的错误。只需添加一个Angular ngclass属性即可。

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

</div>

我的数据绑定和一切都正常。我需要在父组件上做些什么吗?我已经尝试了子组件中的所有生命周期事件。


1
@Maximus 作为入口组件 - Jameel Moideen
1
首先,将 this.renderWidgetInsideWidgetContainer();ngAfterViewInit 移动到 ngOnInit - yurzui
1
@Maximus,感谢您的时间。您的文章太棒了! - Jameel Moideen
1
@JEMI,不客气)我有很多有趣的文章,请查看。 - Max Koretskyi
1
@Maximus 当然。我已经关注你了。你的每一篇文章都非常深入。 - Jameel Moideen
显示剩余10条评论
12个回答

0

RxJS timer()

像其他人建议的那样,您可以通过将代码放在setTimeout(..)函数中来解决问题。这将基本上将执行移动到事件循环堆栈之外,因此进入Angular的下一个变更检测周期。

RxJS有自己的超时实现timer() - 它接受毫秒作为参数并返回一个可观察对象。由于我们只需要在事件循环堆栈清除后(并且Angular完成了所有渲染计算)发生执行,因此我们可以使用没有任何参数的timer()(它将默认为0):

ngAfterViewInit() {
    timer().subscribe(() => {
        // your code here
    })
}

JS事件循环图示:

enter image description here


-2

尝试在ngOnInit()中调用您的代码

someMethod() // emitted method call from output
{
    // Your code 
}

ngOnInit(){
  someMethod(); // call here your error will be gone
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接