Jordan
Jordan

Reputation: 744

using ng-content in ng-template

Is it possible to use <ng-content> (and its select option) inside a <ng-template> or does it only works within a component ?

<ng-container *ngTemplateOutlet="tpl">
  <span greetings>Hello</span>
</ng-container>

<ng-template #tpl>
  <ng-content select="[greetings]"></ng-content> World !
</ng-template>

The above code does just render World ! :(

Here is the live example

Upvotes: 40

Views: 33239

Answers (4)

Max Gaurav
Max Gaurav

Reputation: 1913

It is now possible (testing on Angular 17 to use ng-content inside ng-template)

import { Component } from "@angular/core";
import { NgTemplateOutlet } from "@angular/common";

@Component({
  selector: "app-sample",
  standalone: true,
  imports: [NgTemplateOutlet],
  template: `
   <ng-template #mainContent><ng-content /></ng-template>
   <ng-container *ngTemplateOutlet="mainContent" />
`
})
export class SampleComponent {}

Then in any of the components Html

<app-sample>
  <p>Some work</p>
</app-sample>

Upvotes: 0

Alexander Shagin
Alexander Shagin

Reputation: 505

With some trick it's possible to use a kind of ng-content in ng-template:

    <h2>ngMacro (component)</h2>    

    <ng-template #tpl21 let-ctx>      
      <div>
      <ng-macro-content></ng-macro-content> World {{ctx.mark}}       
      </div>
    </ng-template>

    <ng-macro [template]="tpl21" [context]="{ mark: '!' }">
      Hello
    </ng-macro>

    <ng-macro [template]="tpl21" [context]="{ mark: '!!!' }">
      Hi
    </ng-macro>
    
    <h2>ngMacro (directive)</h2>    

    <ng-template #tpl22 let-ctx>      
      <div>
      <span *ngMacroContent></span>
      World {{ctx.mark}}       
      </div>
    </ng-template>

    <ng-container *ngMacro="tpl22; context: { mark: '!' }" >
      Hello
    </ng-container>

    <span *ngMacro="tpl22; context: { mark: '!!!' }" >
      Hi
    </span>

Exaple on StackBlitz for Angular 14 (can be adapted for earlier versions)

Upvotes: 1

Grochni
Grochni

Reputation: 1851

As far as i know it is not possible using ng-content, but you can provide parameters to the template. So it's possible to pass another NgTemplate, which can again be used with an NgTemplateOutlet inside the original template. Here's a working example:

<ng-container *ngTemplateOutlet="tpl, context: {$implicit: paramTemplate}">
</ng-container>

<ng-template #paramTemplate>
  <span>Hello</span>
</ng-template>


<ng-template #tpl let-param>
  <ng-container *ngTemplateOutlet="param"></ng-container> World !
</ng-template>

Actually it is even possible to pass multiple templates to the original template:

<ng-container *ngTemplateOutlet="tpl, context: {'param1': paramTemplate1, 'param2': paramTemplate2}">
</ng-container>

<ng-template #paramTemplate1>
  <span>Hello</span>
</ng-template>

<ng-template #paramTemplate2>
  <span>World</span>
</ng-template>


<ng-template #tpl let-param1="param1" let-param2="param2">
  <ng-container *ngTemplateOutlet="param1"></ng-container>
  <ng-container *ngTemplateOutlet="param2"></ng-container>
</ng-template>

Upvotes: 45

Jason
Jason

Reputation: 1366

You can use ng-content inside ng-template.

This is something I put together a while back demonstrating putting the ng-content somewhere on dom based on property. look at the html of tabs.component to see this in use.

https://stackblitz.com/edit/mobile-ng-content

Upvotes: -3

Related Questions