I am working on building a Header component in Angular and want to show the navigation at different locations in the DOM structure according to whether an input inputTwoRows
has been set to true/false
. The nav is added to the Header's template via content projection - ng-content
. I have tried to wrap 2 ng-content
in ng-templates
at different locations in the template and added ngIf
to conditionally show them. The templates are, however, attempting to show the same projected content. As you will see in the Stackblitz link demoing the issue only the first ng-content
is shown if [twoRows]="true"
on c-header
. Below is the code for header.component.html
:
<header>
<div>logo</div>
<ng-template [ngIf]="inputTwoRows">
<p>Two Rows</p>
<ng-content select="c-header-nav"></ng-content>
</ng-template>
<div>utils</div>
<ng-template [ngIf]="!inputTwoRows">
<p>One Row</p>
<ng-content select="c-header-nav"></ng-content>
</ng-template>
</header>
This logic works fine if the content inside either ng-template
is not ng-content
. Is there a way I can achieve my original aim somehow?
https://stackblitz.com/edit/angular-ivy-xfr7hs?file=src/app/components/header/header.component.html
Thanks
James
CodePudding user response:
It’s because ng-content happens at the build time. is instantiated when the host component is instantiated and it also means that Angular compiler creates the rule and related JS code when compiling the code. No run-time affects the behavior later. It does not change when the component is updated.
CodePudding user response:
I ended up defining a single <ng-content>
wrapped in an <ng-template>
. I then placed <ng-containers>
where I needed them in the DOM. The outer <ng-containers>
deal with the conditional logic and the inner <ng-containers>
reference the <ng-template>
if required:
<header>
<div>logo</div>
<ng-container *ngIf="!twoRows">
<ng-container *ngTemplateOutlet="headerNavTemplate"></ng-container>
</ng-container>
<div>utils</div>
<ng-container *ngIf="!twoRows">
<ng-container *ngTemplateOutlet="headerNavTemplate"></ng-container>
</ng-container>
<ng-template>
<ng-content select="c-header-nav"></ng-content>
</ng-template>
</header>