4

How parent component pass multiple ng-templates to child component?

Example the Parent component contains multiple ng-templates:

<app-childcomponent> <ng-template>Item A</ng-template> <ng-template>Item B</ng-template> ... </app-childcomponent> 

Child component needs to receive the ng-templates from parent and put inside app-menu:

 <app-menu> <ng-content></ng-content> </app-menu> 

So it will look something like this in the Child component:

<app-menu> <ng-template>Item 1</ng-template> //having trouble sending this to app-menu from parent <ng-template>Item 2</ng-template> //having trouble sending this to app-menu from parent <app-menu> 

but it seems like the ng-content is empty causing app-menu not getting the multiple ng-templates.

 <app-menu> //empty </app-menu> 

What have I tried?

  1. I have tried passing the template via @input. <app-childcomponent [myTemplate]="myTemplate"></child-component>

  2. Template outlet. Result: Child component unable to getng-templates.

Parent html:

<app-childcomponent> <ng-template>Item 1</ng-template> <ng-template>Item 2</ng-template> </app-childcomponent> 

Parent class:

@ContentChild(TemplateRef) templateRef: TemplateRef<any>; 

Child html:

<app-menu> <ng-template [ngTemplateOutlet]="templateRef"></ng-template> <app-menu> 

Expected <ng-template [ngTemplateOutlet]="templateRef"></ng-template> to contain

<ng-template>Item 1</ng-template> <ng-template>Item 2</ng-template> 

but it is empty.

Replying to @Ricardo solution

I tried your update. It was empty as well.

Parent:

<app-childcomponent top-left-menu> <ng-template>Item 1</ng-template> <ng-template>Item 2</ng-template> </app-childcomponent> 

Child:

<ng-content select="[top-left-menu]"></ng-content> 

Also I also tried passing ng-template to ng-content but Print ME! did not get rendered. It was empty. It seems like ng-template dont go into ng-content?

Parent:

<app-childcomponent [contextMenuSubject]="contextmenuSubject"> <ng-template>Print ME!</ng-template> </app-childcomponent> 

Child:

<ng-content></ng-content> 
3
  • 1
    If you send it as input param, then you should use NgTemplateOutlet to dynamically create component from template. What was your result? Commented Feb 26, 2018 at 13:40
  • I sent it as input param and receive as Input()myTemplate type of ElementRef and attempt to draw it with {{ myTemplate }}. I guess this is wrong X.X Commented Feb 27, 2018 at 1:39
  • blog.angular-university.io/… Easy explaination of ng-template and ngTemplateOutlet Commented Jul 22, 2021 at 2:53

1 Answer 1

6

You can declare in your child component a default template with the property ngTemplateOutlet so you can bind a custom one from the parent component

<ng-template [ngTemplateOutlet]="template || defaultTemplate"></ng-template> <ng-template #defaultTemplate let-item="item"> {{item}} </ng-template> 

you should expose template like a variable so the parent component can be used to inject the custom template.

the parent component should look like this

<child-component [template]="customTemplate" ></child-component> <ng-template #customTemplate let-item="item"> {{item.name}} </ng-template> 

Other solution

In your child component, you can declare the ng-content like this:

 <ng-content select="[top-left-menu]"></ng-content> 

then In your parent component, you can use his reference in this way:

<custom-super-component top-left-menu></custom-super-component> 

your custom html/component will be placed in the position of your ng-content

Sign up to request clarification or add additional context in comments.

4 Comments

Hi sounds great! Just curious if there any way to put the template inside the child-component tag? <child-component> or any cleaner way to do this?
@Zainu you can use <ng-content > tag to do it , declare this tag with a name and then refer from the parent component this ng-content tag in the html template that you want to put inside
hi, I have tried in chilldcomponent <ng-content [ngTemplateOutlet]="customTemplate"></ng-content> and ` @ContentChild(TemplateRef) customTemplate: TemplateRef<any>` . In parentcomponent <child-component> <ng-template>Item 1</ng-template> <ng-template>Item 2</ng-template> </child-component>
I have updated with Replying to @Ricardo solution above ^

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.