#angular
#angular
Вопрос:
Я хотел бы вставить динамический список компонентов внутри шаблона родительского компонента, используя директиву ngFor для создания заполнителей узла ng-template для каждого компонента в списке. Что я пробовал:
шаблон компонента, в который будут вставлены динамические компоненты:
<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’ представляют собой массив объектов, содержащих экземпляры динамических компонентов в следующей форме:
[
{ 'component' : DynamicComponent1 },
{ 'component' : DynamicComponent2 }
]
С помощью *ngFor динамические компоненты не отображаются в DOM. Я также попытался создать узел-заполнитель ng-template, жестко закодированный внутри шаблона:
шаблон компонента:
<div >
<ng-template #kalasehost></ng-template>
</div>
<div >
<ng-template #kalasehost></ng-template>
</div>
С помощью этого шаблона разметки динамические шаблоны отображаются так, как ожидалось. Кто-нибудь может сказать мне, что я делаю неправильно, используя директиву ngFor?
Ответ №1:
Я решил эту проблему и написал статью на 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;
})
}
Ответ №2:
Вы пробовали использовать ngComponentOutlet
<div *ngFor="let component of components" [ngComponentOutlet]="component.component"></div>
Комментарии:
1. Я пробовал, но в этой ситуации это не очень полезно… проблема устранена с помощью trackBy внутри цикла ngFor…
Ответ №3:
Наконец, проблема решена с помощью trackBy внутри цикла *ngFor
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 amp;amp; item.id;
}