ShamPooSham
ShamPooSham

Reputation: 2379

Accessing ng-content from component code without a wrapper ViewChild

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

Answers (1)

End
End

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

Related Questions