[英]Angular ExpressionChangedAfterItHasBeenCheckedError inside Dynamic Components
I am going to resolve components dynamically for different statements.我将针对不同的语句动态解析组件。
So, I created one directive and one component for it.所以,我为它创建了一个指令和一个组件。
import { Directive, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[mcmsDynamicHost]'
})
export class DynamicHostDirective {
constructor(
public viewContainerRef: ViewContainerRef
) { }
}
import { AfterViewInit, Component, ComponentFactoryResolver, Input, ViewChild } from '@angular/core';
import { DynamicHostDirective } from '@mcms/ui-kit/dynamic-host/dynamic-host.directive';
@Component({
selector: 'mcms-dynamic-host',
templateUrl: './dynamic-host.component.html',
styleUrls: ['./dynamic-host.component.scss']
})
export class DynamicHostComponent implements AfterViewInit {
@ViewChild(DynamicHostDirective) dynamicHost: DynamicHostDirective;
@Input() component;
constructor(
private componentFactoryResolver: ComponentFactoryResolver
) { }
ngAfterViewInit(): void {
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(this.component);
const viewContainerRef = this.dynamicHost.viewContainerRef;
viewContainerRef.clear();
const componentRef = viewContainerRef.createComponent(componentFactory);
}
}
// component template
<ng-template mcmsDynamicHost></ng-template>
Now I am using them in this way.现在我正在以这种方式使用它们。
<div *ngFor="let item of dashboard">
<mcms-dynamic-host [component]="item.card"></mcms-dynamic-host>
</div>
this.dashboard = [
{cols: 2, rows: 3, y: 0, x: 0, dragEnabled: true, card: WelcomeCardComponent, title: 'Welcome to Municipal CMS!'},
{cols: 1, rows: 3, y: 0, x: 2, dragEnabled: true, card: SiteResumeCardComponent, title: 'Site Resume'},
{cols: 2, rows: 5, y: 3, x: 0, dragEnabled: true, card: TrafficActivityCardComponent, title: 'Traffic activity'},
];
Static components are rendered without any issue that works.静态组件的渲染没有任何问题。 But if I try to bind some values to template inside dynamically resolved components for example *ngFor or even *ngIf, all throws error - ExpressionChangedAfterItHasBeenCheckedError
但是如果我尝试将一些值绑定到动态解析组件中的模板,例如 *ngFor 甚至 *ngIf,都会抛出错误 - ExpressionChangedAfterItHasBeenCheckedError
But when I did this trick,但是当我做这个把戏时,
ngOnInit(): void {
setTimeout(() => {
this.data = [
{ image: 'assets/images/green-icons/page-small.svg', title: 'Pages', count: 5 },
{ image: 'assets/images/green-icons/user-small.svg', title: 'Active Users', count: 7 },
{ image: 'assets/images/green-icons/blog-small.svg', title: 'Blog Post', count: 12, pending: 3 },
{ image: 'assets/images/green-icons/comment-small.svg', title: 'Comments', count: 54, pending: 8 },
{ image: 'assets/images/green-icons/media-small.svg', title: 'Digital Assets', count: 230 },
];
}, 100);
}
no errors.没有错误。 It's bit strange for me, anyway we can go with this, but when I try to use for example @angular/material component there's no way to do this kind of trick.
这对我来说有点奇怪,无论如何我们都可以这样做,但是当我尝试使用例如@angular/material 组件时,就没有办法做这种把戏。
Anyone experieced similar issue?任何人都遇到过类似的问题?
Here goes stackblitz link - https://stackblitz.com/edit/angular-kf3pdw这里是 stackblitz 链接 - https://stackblitz.com/edit/angular-kf3pdw
Try moving the data assignation to the ngAfterViewInit
lifecycle hook instead of ngOninit
尝试将数据分配移动到
ngAfterViewInit
生命周期钩子而不是ngOninit
By the way, dynamic component loading should usually be done by using the CDK Portal顺便说一句,动态组件加载通常应该使用CDK Portal来完成
There was a stupid bug on my code.我的代码有一个愚蠢的错误。 With Angular v9, @ViewChild decorator static flag default is
false
.使用 Angular v9,@ViewChild 装饰器静态标志默认为
false
。 This means resolve query result after change detection runs.这意味着在更改检测运行后解析查询结果。 It should be
true
in order to resolve the query result before change detection runs.为了在更改检测运行之前解析查询结果,它应该是
true
。
Stackblitz updated with the correct answer. Stackblitz 更新了正确答案。 Hope this experience helps others!
希望这个经验可以帮助其他人! Cheers!
干杯!
https://angular.io/api/core/ViewChild#description https://angular.io/api/core/ViewChild#description
https://angular.io/guide/static-query-migration https://angular.io/guide/static-query-migration
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.