Angular Version, die ich verwendet habe - Angular 4.2.0
Angular 4 wurde mit ComponentFactoryResolver entwickelt , um Komponenten zur Laufzeit zu laden. Dies ist eine Art der gleichen Implementierung von $ compile in Angular 1.0, die Ihren Anforderungen entspricht
In diesem Beispiel lade ich die ImageWidget- Komponente dynamisch in eine DashboardTileComponent
Um eine Komponente zu laden, benötigen Sie eine Direktive, die Sie auf ng-template anwenden können, um die dynamische Komponente zu platzieren
WidgetHostDirective
import { Directive, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[widget-host]',
})
export class DashboardTileWidgetHostDirective {
constructor(public viewContainerRef: ViewContainerRef) {
}
}
Diese Anweisung fügt ViewContainerRef ein , um Zugriff auf den Ansichtscontainer des Elements zu erhalten, in dem die dynamisch hinzugefügte Komponente gehostet wird.
DashboardTileComponent (Platzhalterkomponente zum Rendern der dynamischen Komponente platzieren)
Diese Komponente akzeptiert eine Eingabe, die von einer übergeordneten Komponente stammt, oder Sie können sie basierend auf Ihrer Implementierung von Ihrem Service laden. Diese Komponente übernimmt die Hauptrolle beim Auflösen der Komponenten zur Laufzeit. In dieser Methode sehen Sie auch eine Methode namens renderComponent (), die letztendlich den Komponentennamen von einem Dienst lädt und mit ComponentFactoryResolver auflöst und schließlich Daten für die dynamische Komponente festlegt .
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
Dies ist eine Service Factory, um alle Komponenten zu registrieren, die Sie dynamisch auflösen möchten
import { Injectable } from '@angular/core';
import { ImageTextWidgetComponent } from "../templates/ImageTextWidget.Component";
@Injectable()
export class WidgetComponentService {
getComponent(componentName:string) {
if(componentName==="ImageTextWidgetComponent"){
return ImageTextWidgetComponent
}
}
}
ImageTextWidgetComponent (Komponente, die wir zur Laufzeit laden)
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() { }
}
Hinzufügen Fügen Sie diese ImageTextWidgetComponent schließlich als entryComponent zu Ihrem App-Modul hinzu
@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;
}
Originalreferenz aus meinem Blog
Offizielle Dokumentation
Laden Sie den Beispielquellcode herunter