'Create multiple different dynamic components using ngFor directive Angular
I would like to insert a dynamic list of components inside parent component template using ngFor directive to create ng-template host placeholders for each component in the list. What I have tried:
component template where dynamic components will be inserted:
<div *ngFor="let component of components;let i = index">
<ng-template #dynamiccomponenthost></ng-template>
</div>
component.ts
@Input()
components: any;
@ViewChildren('dynamiccomponenthost', { read: ViewContainerRef }) cHost: QueryList<ViewContainerRef>;
ngAfterViewInit() {
this.loadComponents();
}
private loadComponents(): void {
this.cHost.map((vcr: ViewContainerRef, index: number) => {
const factory = this.componentFactoryResolver.resolveComponentFactory(this.components[index].component);
vcr.clear();
vcr.createComponent(factory);
});
'components' input is an array of objects containing the dynamic component instances in the following form:
[
{ 'component' : DynamicComponent1 },
{ 'component' : DynamicComponent2 }
]
Using *ngFor the dynamic components are not rendered in the DOM. I have tried also to create ng-template placeholder host hardcoded inside the template:
component template:
<div >
<ng-template #kalasehost></ng-template>
</div>
<div >
<ng-template #kalasehost></ng-template>
</div>
Using this template markup dynamic templates are rendered as expected. Could anyone tell me what I am doing wrong using ngFor directive?
Solution 1:[1]
Have you tried using ngComponentOutlet
<div *ngFor="let component of components" [ngComponentOutlet]="component.component"></div>
Solution 2:[2]
Finally, the provblem solved by using trackBy inside *ngFor loop
component.html:
<div *ngFor="let component of components;trackBy:identify;let i = index">
<ng-template #dynamiccomponenthost></ng-template>
</div>
component.ts:
identify(index, item) {
return item && item.id;
}
Solution 3:[3]
I solved this problem and write an article on medium https://medium.com/@teslenkooleg2017/angular-13-create-multiple-dynamic-components-using-directive-ngfor-effe0850a69d
//component.html
<div *ngFor="let car of cars">
<ng-template #dynamic></ng-template>
</div>
// component.ts
@ViewChildren('dynamic', {read: ViewContainerRef}) dynamic: QueryList<ViewContainerRef>;
private loadComponent(): void {
this.dynamic.map((vcr: ViewContainerRef, index: number) =>{
vcr.clear();
this.componentRef = vcr.createComponent(DynamicComponent);
this.componentRef.instance.title = this.cars[index].title;
this.componentRef.instance.text = this.cars[index].text;
})
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Poul Kruijt |
| Solution 2 | tsiro |
| Solution 3 |
