I have a child component which accept a TemplateRef as an @Input and displays it through ngTemplateOutlet. How can I use @ViewChild/@ViewChildren to retrieve components inside the template ?
If the template is declared in the same component that where it is used, @ViewChild/@ViewChildren are working but it makes the component very less dynamic.
I also tried using @ContentChildren but it makes no difference.
I created a stackblitz in order to reproduce. Here are some of the code:
child.component.html
<ng-container #fromParent [ngTemplateOutlet]="template"></ng-container>
child.component.ts
@Component({
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css'],
})
export class ChildComponent implements AfterViewInit {
@Input() template: TemplateRef<unknown>;
@ViewChildren(HelloComponent) hello = new QueryList<HelloComponent>();
ngAfterViewInit() {
console.log('Has hello', this.hello.length > 0);
}
}
parent.component.html
<ng-template #tmp> <hello name="{{ name }}"></hello> </ng-template>
<app-child [template]="tmp"> </app-child>
The log in child component returns false.
Here is the stackblitz: https://stackblitz.com/edit/angular-eopzyw?file=src/app/app.component.ts
Thank you.
This is interesting, at first look, I too thought that it should be accessible, but did some debugging and found that:
The parent template is part of the parent component host view and hence the
ViewChildrenin child component will not be able to access it as it is not the part of child component host view.Look at the below picture, app component has a host id 165 and the parent ng template gets associated with it.
So it appears that in the current design of
ViewChildrenit does not support querying the templates passed from a host view. May be opening a feature request will be a good idea.