I have a component that uses content projection.
<ng-content select="button">
</ng-content>
I want to do something like this in my component:
@ContentChild('button') button: ElementRef;
However, when I check this.button
, it is undefined
both in ngAfterViewInit
and ngAfterContentInit
.
How can I select my content child if it is a native element and not a custom component?
The important thing to understand is that the selector you pass to @ContentChild
is not a CSS selector, and you cannot find a content child based on its ID, class or element type. You can only search on the identifier name you gave it using the #
operator.
So given a component called my-comp
and the following usage:
<my-comp><button #buttonName>Click me</button></my_comp>
You can find it using:
@ContentChild('buttonName') button: ElementRef;
Edit
As noted in the OP's comment on ckTag's answer (he beat me to it by a minute), that does mean the calling code will need to know you expect the content to be tagged with a specific name.
If your component does actually need to know detail of its content children, the better answer is actually to provide the directive type to @ContentChild
:
@ContentChild(MyButtonComponent, { read: ElementRef })
button: ElementRef;
This is also better, because you can now realistically expect to know the type of content; the calling code can stick #button
on a div
if it feels like it, after all.
That does mean saying goodbye to using a regular HTML button
element, but comes with other benefits. You could, for example, provide a message to guide your calling code, like this:
<ng-content></ng-content>
<div *ngIf="button">Error: Please provide a MyButtonComponent</div>