42

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

2
  • AFAIK the answer is "No", because ng-content applies on component level, not template level. I won't post it as an answer since I'm not 100% it can't be changed, but I'm fairly sure. Commented Aug 21, 2018 at 15:56
  • You may be able to do something with portals and pass a portal as a parameter. material.angular.io/cdk/portal/overview Commented Feb 26, 2021 at 18:06

4 Answers 4

46

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> 
Sign up to request clarification or add additional context in comments.

2 Comments

Is it possible to pass params (ngTemplateOutletContext) to the param templates?
Sure, if they are part of the context you pass to the parent template, you could just have something like this: <ng-template #tpl letTemplate1="template1" let-templateParam1="templateParam1"> <ng-container *ngTemplateOutlet="template1; context: { param1: templateParam1 }"></ng-container> </ng-template>
2

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> 

1 Comment

This is not what is OP asking for. The content passed into template is from component content, not the container content.
1

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)

Comments

-3

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

10 Comments

seems like the example is not doing what i wished for. it's the content of your tab component (<tab>my content</tab>) which is rendered into some of its inner template (mobile or desktop)
You asked about putting ng-content inside ng-template. that example does that
yes but it falls into the "only works within a component" because the content comes from completely outside the current template
Mr. Jason Edwards -- thank you. This was EXACTLY what I was looking for. Honestly, I can't understand why Jordan doesn't find this solvent.
@Cody that’s true. I agree the question is poorly worded and I don’t think this question should be downvoted as a result (except it would be better if the explanation could be in the answer instead of in stack blitz only). But I also understand why it doesn’t do what the OP was wanting to do, because the content that is output in the my-content in the tab component isn’t coming from elsewhere inside the tab component, it is coming from the parent app component. That’s what the “ or does it…” part of the question means. The OP also clarified this in a comment on the answer.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.