Home > Net >  Angular - show projected content in different locations via conditional logic
Angular - show projected content in different locations via conditional logic

Time:07-28

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>

  • Related