在ngIf中动态创建组件

时间:2018-06-11 01:32:35

标签: angular

我正在使用Angular 6而我已经尝试按照here的说法进行操作但是我无法使用它

export class AppComponent implements AfterContentInit, AfterViewInit {
  defaultToTrue = true;
  @ViewChildren('parent', { read: ViewContainerRef }) parent: QueryList<ViewContainerRef>;

  constructor(private cfr: ComponentFactoryResolver) { }

  ngAfterViewInit(){
    const resolve = this.cfr.resolveComponentFactory(ChildComponent);
    this.parent.changes.subscribe(changes => {
      this.parent.createComponent(resolve); //Error
    });
  }

}

HTML:

<div *ngIf="defaultToTrue">
  <div #parent></div>
</div>

StackBlitz

2 个答案:

答案 0 :(得分:2)

要摆脱ExpressionChangedAfterItHasBeenCheckedError,您可以使用this Angular In Depth blog post中建议的技巧之一:

使用ChangeDetectorRef.detectChanges 检测强制更改:

constructor(private cfr: ComponentFactoryResolver, private cd: ChangeDetectorRef) { }

ngAfterViewInit(){
  const resolve = this.cfr.resolveComponentFactory(ChildComponent);
  this.parent.changes.subscribe(changes => {
    this.parent.createComponent(resolve);
    this.cd.detectChanges();  // Trigger change detection
  });
}

使用setTimeout

异步创建组件
ngAfterViewInit(){
  const resolve = this.cfr.resolveComponentFactory(ChildComponent);
  this.parent.changes.subscribe(changes => {
    setTimeout(() => { this.parent.createComponent(resolve); });
  });
}

答案 1 :(得分:0)

我的情况是#container位于2 *ngFor的内部,而所有*ngIf内部

我什至可以获取ViewContainerRefQueryList<ViewContainerRef>的实例的唯一方法是在ngAfterViewChecked中,并且仅在条件之内,甚至是在运行setTimeout的情况下,< / p>

编辑:必须添加一个标记才能停止,否则该标记会不断运行

if (this.fieldsContainer && this.componentsGenerated == false) {
  this.componentsGenerated = true
  setTimeout(this.generateComponents.bind(this))
}

EDIT2: 最终需要更多的代码来处理所有这些,并将changeDetection: ChangeDetectionStrategy.OnPushcd:ChangeDetectorRef

一起使用
ngAfterViewChecked(): void {

  if (this.fieldsContainersQuery && this.componentsGenerated == false) {
    this.componentsGenerated = true

    this.fieldsContainersQuery.changes.subscribe(changes=>{
      this.fieldsContainersQuery.forEach(fieldContainerItem => this.generateComponents(fieldContainerItem))
      this.cd.detectChanges()
   })
 }

更多详细信息

blog github