简体   繁体   English

动态组件中的 Angular ExpressionChangedAfterItHasBeenCheckedError

[英]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.

相关问题 角动态组件和ExpressionChangedAfterItHasBeenCheckedError - Angular Dynamic Components and ExpressionChangedAfterItHasBeenCheckedError Angular Primeng 组件上的 ExpressionChangedAfterItHasBeenCheckedError - Angular ExpressionChangedAfterItHasBeenCheckedError on Primeng Components ExpressionChangedAfterItHasBeenCheckedError:具有两个同级Angular组件 - ExpressionChangedAfterItHasBeenCheckedError: with two sibling Angular components Angular动态组件加载 - ExpressionChangedAfterItHasBeenCheckedError - Angular dynamic component loading - ExpressionChangedAfterItHasBeenCheckedError Angular 4动态页面加载器:ExpressionChangedAfterItHasBeenCheckedError - Angular 4 dynamic page loader : ExpressionChangedAfterItHasBeenCheckedError Angular中动态模板管理期间的ExpressionChangedAfterItHasBeenCheckedError - ExpressionChangedAfterItHasBeenCheckedError during dynamic template management in Angular ExpressionChangedAfterItHasBeenCheckedError:角度 - ExpressionChangedAfterItHasBeenCheckedError: angular ExpressionChangedAfterItHasBeenCheckedError Angular - ExpressionChangedAfterItHasBeenCheckedError Angular Angular 4 ExpressionChangedAfterItHasBeenCheckedError - Angular 4 ExpressionChangedAfterItHasBeenCheckedError 反应形式动态表单验证中的 angular 6“ExpressionChangedAfterItHasBeenCheckedError”添加和删除 - angular 6 "ExpressionChangedAfterItHasBeenCheckedError" in reactive form dynamic form validation add and remove
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM