0

I want to render my rather simple component always with a default <ng-content> and optionally with a named ng-content. If that named ng-content exists, it should be wrapped by additional html. I did find a a solution, but annoyingly I need two references for it:

app.component.html (where it get's used)

<app-header>
    A minimal header
</app-header>
<hr>

<app-header>
    A full header
    <h2 #two two>a subhead</h2>
</app-header>

my component

import { Component, OnInit, ContentChild, ElementRef } from '@angular/core';

@Component({
    selector: 'app-header',
    templateUrl: './header.component.html'
})
export class HeaderComponent {
    @ContentChild('two', {static: false}) twoRef: ElementRef;
}

the header.component.html

<h4>default content</h4>
<ng-content>
</ng-content>

<h4>named contents</h4>

<div *ngIf="twoRef">
    <b style="color: purple">
        <ng-content select="[two]"></ng-content>
    </b>
</div>
<ng-template [ngIf]="twoRef">TWO exists B</ng-template>

Result is as expected, but I dislike the two attributes I need:

<h2 #two two>

→ is there a better way, to get along with just one reference / attrib ?

Frank N
  • 9,625
  • 4
  • 80
  • 110

1 Answers1

1

you can do a helper empty directive and query it with ContentChild

@Directive({selector: '[two]'}) export class MyProjectionDirective {}
....
@ContentChild(MyProjectionDirective) ref: MyProjectionDirective;

then only <h2 two> would be required to use that component

Andrei
  • 10,117
  • 13
  • 21
  • Working. thank you! But regrettable is, that I need to import specific Directive(s) to whereever I intend to use my template... (not as self-sufficient as desirable) – Frank N Feb 14 '20 at 09:55
  • 1
    you can make module with `HeaderComponent` and `MyProjectionDirective` in exports and always import them as pair wherever you need – Andrei Feb 14 '20 at 09:58