angular - Rendera komponent dynamiskt
Jag har denna array:
this.dashboard = [
{name: '<app-incassi-provvigioni></app-incassi-provvigioni>'},
{name: '<app-scheda-punti-vendita></app-scheda-punti-vendita>'}
]
Jag fyller denna array på ngOnInit-cykeln. Jag undrade hur jag kan rendera komponenterna när jag läser min array i HTML på det sättet:
<gridster [options]="gridsterOptions">
<gridster-item [item]="item" *ngFor="let item of dashboard">
<!-- your content here -->
{{item.name}}
</gridster-item>
</gridster>
Självklart returnerar det just nu strängen som finns i objektet, men jag försöker hitta en lösning för att rendera komponenten. Är det möjligt att göra det?
Mer detaljer: Jag utvecklar en dashboard-typ av app där jag hämtar listan över användarens dashlet från databasen och jag försöker rendera dessa komponenter dynamiskt när huvudapp-komponenten är klar. Använder Angular 7 och Gridster2.
Svar #1
Du kan injicera komponent dynamiskt
Skapa bara komponent med @Input() komponent;
export class DynamicContentComponent implements OnInit {
@Input() component: any;
@Input() data: any;
constructor(public viewContainerRef: ViewContainerRef,
private componentFactoryResolver: ComponentFactoryResolver) { }
ngOnInit() {
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(this.component);
this.viewContainerRef.clear();
const componentRef = this.viewContainerRef.createComponent(componentFactory);
(<DynamicComponentRef>componentRef.instance).data = this.data;
}
}
Och använd det i HTML
<app-dynamic-content [component]="someComponent" [data]="data"></app-dynamic-content>
Dataexempel
someComponent = SchedaPuntiVendita;
Dynamiska komponenter bör läggas till i entryComponents i din module
Du kan också skapa någon slags fabrik som tar emot en sträng och beroende på den returnerar dig komponentklassen
Fabrikexempel
@Injectable()
export class DynamicContentComponentFactory {
constructor() { }
get(type: ContentType): any {
switch (type) {
case 'scheda':
return SchedaPuntiVendita;
}
}
Och ändra DynamicContentComponent lite
@Input() contentType: string;
constructor(..., private factory: DynamicContentComponentFactory) { }
...
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(this.factory.get(this.contentType));
...
Svar #2
Istället för att skicka komponenttaggens namn ("app-incassi-provvigioni" i ditt fall), skicka komponentnamnet (TestComponenet), sedan kalla på funktionen från din vy och rendera den dynamiskt med Directive.
t.ex :
<gridster [options]="gridsterOptions">
<gridster-item [item]="item" *ngFor="let item of dashboard">
<div class="inner">
<ng-template dynamic-template> </ng-template>
</div>
</gridster-item>
</gridster>
dynamic-template är en direktiv som hjälper oss att ladda komponenten.
