I'm trying to pass a different template for each field of an array of string.
TS
export class MyComponent {
fields = ['name', 'person.age', 'created_at', ...]
}
HTML
<div *ngFor="let field of fields">
<ng-container [ngTemplateOutlet]="field">
</ng-container>
</div>
<ng-template #name>
Name template
</ng-template>
<ng-template #created_at>
Created at template
</ng-template>
<ng-template #person.age>
person.age template
</ng-template>
I obviously get an error because the ngTemplateOutlet
expects a TemplateRef
instead of a string. But how can I pass it a string dynamically to refer to the correct template? The error I get is:
Error : templateRef.createEmbeddedView is not a function
PS: There might be better solutions for this problem. Don't hesitate to share :) Thank you!
Would you try this? (it works for me):
export class YourClass {
@ViewChild('ciao') ciao: TemplateRef<any>;
@ViewChild('ciao2') ciao2: TemplateRef<any>;
fields: TemplateRef<any>[];
constructor () {
this.fields = [this.ciao, this.ciao2];
}
}
<ng-template #ciao></ng-template>
<ng-template #ciao2></ng-template>
You can write it like such:
<div *ngFor="let field of fields">
<ng-container *ngTemplateOutlet="{'name': name, 'created_at': created_at,
'person_age': person_age}[field]">
</ng-container>
</div>
<ng-template #name>
Name template
</ng-template>
<ng-template #created_at>
Created at template
</ng-template>
<ng-template #person_age>
person.age template
</ng-template>
This doesn't require child component.
See comment for the workaround to pass the reference using the typescript. I just wanted to mention a second solution for those having the same problem : Use ngSwitch :)
<div *ngFor="let field of fields">
<div [ngSwitch]="field">
<div *ngSwitchCase="'name'">
{{ field }}
</div>
<div *ngSwitchCase="'person.age'">
{{ var[field] }} is my age
</div>
<div *ngSwitchDefault>
fallback
</div>
</div>
You could create the templates in the parent component, and pass a list of templates as input to the child component :
<my-child [templates]="{'name': name, 'created_at': created_at, 'person_age': person_age}"></my-child>
<ng-template #name>
Name template
</ng-template>
<ng-template #created_at>
Created at template
</ng-template>
<ng-template #person_age>
person.age template
</ng-template>
Then you can simply use the templates :
<ng-container *ngFor="let f of fields">
<ng-container *ngTemplateOutlet="templates[f]">
</ng-container>
</ng-container>
Here is a stackblitz running code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With