ViewChildren 与 templateRef

ViewChildren with templateRef

我想使用 ViewChildrenTemplateRef 生成 QueryList,但无法传递到输入组件。

例如

Component.ts:

@ViewChildren(TemplateRef) cellTemplates: QueryList<TemplateRef<any>>;

查看:

<my-component [templatesRef]="cellTemplates"></my-component>

输入:

_templatesRef;
@Input()
set templatesRef(refs: any) {
   this._templatesRef = refs;
}

ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'ngIf: false'. Current value: 'ngIf: true'.

参见Stackbilitz

从模板中获取 cellTemplates 后,您应该强制父级检测更改,因此请尝试在父级中使用 ChangeDetectorRef:

export class AppComponent  {
  name = 'Angular';
  @ViewChildren(TemplateRef, {read: TemplateRef}) cellTemplates: QueryList<TemplateRef<any>>;
  constructor(private cd: ChangeDetectorRef) { }
  ngOnInit(){ }
  ngAfterViewInit(){
    this.cd.detectChanges();
  }
}

您可以在 article.

中找到有关该异常的详细解释

DEMO

为什么不使用您创建的视图变量呢?

<my-component [templatesRef]="title"></my-component>

<ng-template #title>
    ok
</ng-template>

一个丑陋的解决方法是,在您的应用程序组件中

<my-component *ngIf="yet" [templatesRef]="cellTemplates"></my-component>

实施 afterViewInit 并使用 setTimeout

export class AppComponent implements AfterViewInit  {
  yet=false;

  ngAfterViewInit()
  {
    setTimeout(()=>{
      this.yet=true
    })
  }
}

问题是起初 cellTemplates 是一个空查询,afterViewInit 获取元素,

不使用 ChangeDetectorRef & setTimeout 的另一种解决方案。

@ViewChildren(TemplateRef, {read: TemplateRef})
set cellTemplates(refs: QueryList<TemplateRef<any>>) {
    this._cellTemplates = refs;
}