Reputation: 2379
Let's say I have a component called RecursiveComponent (with a selector named recursive). It has a number "identifier" as input, as well as accepting more RecursiveComponents in its body. So the HTML code that uses this component may look like this:
<recursive identifier="1">
<recursive identifier="2">
<recursive identifier="3"></recursive>
</recursive>
<recursive identifier="4"></recursive>
</recursive>
For simplicity, the component only outputs "identifier has x children" and then the inserted body which is done through <ng-content>
. This works, but to figure out how many children components there are, I have to wrap the ng-content with a ViewChild and look at the nativeElement's childNodes, which I feel is a little overkill. This is what the component code looks like:
@Component({
selector: 'recursive',
template: `
{{identifier}} has {{noOfChildren}} children
<div #contentRef>
<ng-content select="recursive"></ng-content>
</div>`
})
export class RecursiveComponent implements OnChanges {
@ViewChild('contentRef', { read: ElementRef }) contentRef: ElementRef;
@Input() identifier: number;
noOfChildren: number;
ngOnChanges() {
if (this.contentRef) {
this.noOfChildren = this.contentRef.nativeElement.childNodes.length;
}
}
}
Is there a better and more Angular-like way to access the ng-content from within the component code? This feels like a hack.
Working demo: https://stackblitz.com/edit/angular-wz8zu6
Upvotes: 4
Views: 2395
Reputation: 626
I think this is probably the only way you can do something like this, you need access to the elements in the DOM. There is however another (Possibly better) way of doing this with @ViewChildren.
You can use ViewChildren to get the QueryList of elements or directives from the view DOM. Any time a child element is added, removed, or moved, the query list will be updated, and the changes observable of the query list will emit a new value.
https://angular.io/api/core/ViewChildren#viewchildren
Upvotes: 2