Version angulaire que j'ai utilisée - Angular 4.2.0
Angular 4 est venu avec ComponentFactoryResolver pour charger les composants au moment de l'exécution. C'est une sorte de même implémentation de $ compile dans Angular 1.0 qui répond à vos besoins
Dans cet exemple ci-dessous, je charge le composant ImageWidget dynamiquement dans un DashboardTileComponent
Afin de charger un composant, vous avez besoin d'une directive que vous pouvez appliquer à ng-template qui aidera à placer le composant dynamique
WidgetHostDirective
import { Directive, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[widget-host]',
})
export class DashboardTileWidgetHostDirective {
constructor(public viewContainerRef: ViewContainerRef) {
}
}
cette directive injecte ViewContainerRef pour accéder au conteneur de vue de l'élément qui hébergera le composant ajouté dynamiquement.
DashboardTileComponent (composant d'espace réservé pour le rendu du composant dynamique)
Ce composant accepte une entrée provenant d'un composant parent ou vous pouvez charger à partir de votre service en fonction de votre implémentation. Ce composant joue le rôle principal pour résoudre les composants lors de l'exécution. Dans cette méthode, vous pouvez également voir une méthode nommée renderComponent () qui charge finalement le nom du composant à partir d'un service et le résout avec ComponentFactoryResolver et enfin la définition des données sur le composant dynamique.
import { Component, Input, OnInit, AfterViewInit, ViewChild, ComponentFactoryResolver, OnDestroy } from '@angular/core';
import { DashboardTileWidgetHostDirective } from './DashbardWidgetHost.Directive';
import { TileModel } from './Tile.Model';
import { WidgetComponentService } from "./WidgetComponent.Service";
@Component({
selector: 'dashboard-tile',
templateUrl: 'app/tile/DashboardTile.Template.html'
})
export class DashboardTileComponent implements OnInit {
@Input() tile: any;
@ViewChild(DashboardTileWidgetHostDirective) widgetHost: DashboardTileWidgetHostDirective;
constructor(private _componentFactoryResolver: ComponentFactoryResolver,private widgetComponentService:WidgetComponentService) {
}
ngOnInit() {
}
ngAfterViewInit() {
this.renderComponents();
}
renderComponents() {
let component=this.widgetComponentService.getComponent(this.tile.componentName);
let componentFactory = this._componentFactoryResolver.resolveComponentFactory(component);
let viewContainerRef = this.widgetHost.viewContainerRef;
let componentRef = viewContainerRef.createComponent(componentFactory);
(<TileModel>componentRef.instance).data = this.tile;
}
}
DashboardTileComponent.html
<div class="col-md-2 col-lg-2 col-sm-2 col-default-margin col-default">
<ng-template widget-host></ng-template>
</div>
WidgetComponentService
Il s'agit d'une fabrique de services pour enregistrer tous les composants que vous souhaitez résoudre dynamiquement
import { Injectable } from '@angular/core';
import { ImageTextWidgetComponent } from "../templates/ImageTextWidget.Component";
@Injectable()
export class WidgetComponentService {
getComponent(componentName:string) {
if(componentName==="ImageTextWidgetComponent"){
return ImageTextWidgetComponent
}
}
}
ImageTextWidgetComponent (composant que nous chargeons au moment de l'exécution)
import { Component, OnInit, Input } from '@angular/core';
@Component({
selector: 'dashboard-imagetextwidget',
templateUrl: 'app/templates/ImageTextWidget.html'
})
export class ImageTextWidgetComponent implements OnInit {
@Input() data: any;
constructor() { }
ngOnInit() { }
}
Ajouter Enfin, ajoutez ce ImageTextWidgetComponent à votre module d'application en tant qu'entréeComponent
@NgModule({
imports: [BrowserModule],
providers: [WidgetComponentService],
declarations: [
MainApplicationComponent,
DashboardHostComponent,
DashboardGroupComponent,
DashboardTileComponent,
DashboardTileWidgetHostDirective,
ImageTextWidgetComponent
],
exports: [],
entryComponents: [ImageTextWidgetComponent],
bootstrap: [MainApplicationComponent]
})
export class DashboardModule {
constructor() {
}
}
TileModel
export interface TileModel {
data: any;
}
Référence originale de mon blog
Documentation officielle
Télécharger un exemple de code source