How can I get a collection of all templates (TemplateRef) inside a component? It works fine with ViewChild but ViewChildren is undefined...
I use a solution from this question. Plunker with the full example.
@Component({
selector: 'my-app',
template: `
<div>
<template #model>...</template>
<template #color>...</template>
</div>`
})
export class App {
@ViewChild('model') model;
@ViewChild('color') color;
@ViewChildren(TemplateRef) templates: QueryList<TemplateRef>;
ngAfterContentInit() {
console.log(this.templates); // undefined
console.log(this.model); // TemplateRef_ {...}
}
}
I need templates
for a grid component where it's possible to define templates for columns. Unfortunately ng-content doesn't support dynamic projection, so I'm trying to achieve it with templates.
You can't directly access the elements from the templateRef. You need to follow the same process using @ViewChildren. The elementRef that is available on the templateRef as shown here just points to the DOM host element that Angular created for the template element - it's a comment node.
Angular @ViewChildren. Angular @ViewChildren Decorator is used to get the QueryList of elements or directives from the view DOM. When a new child element is added or removed, the QueryList will be updated and its changes function will emit new value. @ViewChildren sets the data before ngAfterViewInit callback.
ViewChild returns a ElementRef, which is nothing but a wrapper around the native HTML element. There could be multiple instances of the same component or element in the Template. The ViewChild always returns the first component.
When a new child element is added or removed, the QueryList will be updated and its changes function will emit new value. @ViewChildren sets the data before ngAfterViewInit callback.
If you move console.log('child', this.templates);
to ngAfterViewInit()
then it works.
ngAfterViewInit() {
console.log('child', this.templates);
}
I had expected it to work in ngAfterContentInit()
as well. It seems in this Angular version ngAfterContentInit()
runs before ngAfterViewInit()
. I was sure this was the other way around earlier.
Plunker example
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With