Reputation: 209
I want to use ViewChildren
make QueryList
from TemplateRef
, but can't pass to input component.
For example
Component.ts:
@ViewChildren(TemplateRef) cellTemplates: QueryList<TemplateRef<any>>;
View:
<my-component [templatesRef]="cellTemplates"></my-component>
Input :
_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'.
See in Stackbilitz
Upvotes: 2
Views: 8194
Reputation: 209
Another solution without using ChangeDetectorRef
& setTimeout
.
@ViewChildren(TemplateRef, {read: TemplateRef})
set cellTemplates(refs: QueryList<TemplateRef<any>>) {
this._cellTemplates = refs;
}
Upvotes: 0
Reputation: 57971
An ugly work around is, in your app-component
<my-component *ngIf="yet" [templatesRef]="cellTemplates"></my-component>
Implements afterViewInit and use a setTimeout
export class AppComponent implements AfterViewInit {
yet=false;
ngAfterViewInit()
{
setTimeout(()=>{
this.yet=true
})
}
}
The problem is that at first cellTemplates is a empty query and afterViewInit get elements,
Upvotes: 2
Reputation: 21638
Why not use the view variable you created instead?
<my-component [templatesRef]="title"></my-component>
<ng-template #title>
ok
</ng-template>
Upvotes: 0
Reputation: 11982
You should force parent to detect changes after getting the cellTemplates from template, so try to use ChangeDetectorRef in parent:
export class AppComponent {
name = 'Angular';
@ViewChildren(TemplateRef, {read: TemplateRef}) cellTemplates: QueryList<TemplateRef<any>>;
constructor(private cd: ChangeDetectorRef) { }
ngOnInit(){ }
ngAfterViewInit(){
this.cd.detectChanges();
}
}
You can find detailed explanations about that exception in this article.
Upvotes: 4