Home > Enterprise >  Get elements from <ng-content></ng-content> of the same component in ts file
Get elements from <ng-content></ng-content> of the same component in ts file

Time:11-29

I am trying to get elements from ng-content which is present in the same component, but I am unable to get them.

Component html

<div>
<ng-content #action></ng-content>
<app-comp2></app-comp2>
</div>

Component's .ts

@ContentChildren('action') content:QueryList<ElementRef>;

I am always getting undefined. What could be the reason?

CodePudding user response:

I think you are trying to get this.content inside onInit, ng-content will not be available till the ngAfterContentInit hook is called. Try using this.content inside ngAfterContentInit or ngAfterViewInit

ngAfterContentInit(){
  console.log(this.content)
}

CodePudding user response:

The documentation mentions the selector inside @ContentChildren selects a template reference in the content. Example: Parent.html

<app-content-component>
  <div id="div1" #action>This is the content of component</div>
  <div id="div2">This is other content of component</div>
</app-content-component>

Component.ts

// this now contains div1 but not div2
@ContentChildren('action') content: QueryList<ElementRef>;

It is not possible to get all the Elements in the content with @ContentChildren. You can only use the selector for the following cases:

The following selectors are supported.

  • Any class with the @Component or @Directive decorator
  • A template reference variable as a string (e.g. query <my-component #cmp> with @ContentChildren('cmp'))
  • Any provider defined in the child component tree of the current component (e.g. @ContentChildren(SomeService) someService: SomeService)
  • Any provider defined through a string token (e.g. @ContentChildren('someToken') someTokenVal: any)
  • A TemplateRef (e.g. query with @ContentChildren(TemplateRef) template;)

As you actually project the content with ng-content you can actually use @ViewChild to get the content, but not on the ng-content element directly as it will be replaced by the content. You can however just wrap the ng-content in a ng-container and add a template variable to it. Example:

Component.html

<div>
  <ng-container #myContent>
    <ng-content></ng-content>
  <ng-container>
  <app-comp2></app-comp2>
</div>

Component.ts

// this now contains a reference to the ng-container
@ViewChild('myContent') content: ElementRef;
  • Related