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>
✓ 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]