Home > Blockchain >  Use ng-template in the child component from the parent component
Use ng-template in the child component from the parent component

Time:07-26

I have the following component for render a list of options. optionsList input gets a list that needs to be rendered with a custom format provided from the item input.

list-box.component.html

<div *ngFor="let option of optionsList; index as it">
  <ng-container [ngTemplateOutlet]="item"></ng-container>
</div>

list-box.component.ts

@Component({
  selector: 'app-list-box',
  templateUrl: './list-box.component.html'
})
export class ListBoxComponent implements OnInit {
  @Input('item') public item!:TemplateRef<any>;
  @Input('optionsList') optionsList:any[]=[];
  ...
}

Then, in a parent component I have a template that contains the format for render each item, and send it to the list-box component for the task:

In the parent.component.html

<ng-template let-option pTemplate="item" #item>
  <label>{{it}}: {{option.name}}</label>
</ng-template>

<app-list-box
  [optionsList]="[{'name': '...'}, ...]"
  [item]="item">
</app-list-box>

This code obviously doesn't work, it shows the error that option and it don't exist in the parent.

The question is, How can I send a particular format to render each item in the child component?.

I can use a specific format in the child component, but if the list of items has other type of items with different fields, then the list-box component is not useful, and I would need to create another specific component or map the content from the list to set the names of the required fields, but it is not desired.

P.S. For this writing, I simplified the code using ngfor, because in practical terms it is what I require. I don't want to put the ngFor in the parent to set all the items there, the sample code is a simulation of an imported module that I want to customize.

CodePudding user response:

You have to pass the context to the ngTemplateOutlet

<div *ngFor="let option of optionsList; index as it">
  <ng-container
    [ngTemplateOutlet]="item"
    [ngTemplateOutletContext]="{ option: option, it: it }">
  </ng-container>
</div>

And change ng-template to receive this parameter

<ng-template let-option="option" let-it="it" pTemplate="item" #item>
  <label>{{it}}: {{option.name}}</label>
</ng-template>

CodePudding user response:

Taking into account the following code:

parent.component.html:

<ng-template let-option pTemplate="item" #item>
  <label>{{it}}: {{option.name}}</label>
</ng-template>

<app-list-box
  [optionsList]="[{'name': '...'}, ...]"
  [item]="item">
</app-list-box>
  1. ✓ I can see that the parameter let-option is implicit, this is because it is not being assigned to a specific element of the context. (example: let example="something") [Valid]

  • Related