Das Integrieren einer dynamischen Component wird hier einfachheitshalber direkt in „app.component.ts“ definiert.
//app.component.ts
@NgModule({
imports: [BrowserModule],
declarations: [App],
bootstrap: [App]
})
export class AppModule { }
Für Demonstationszwecke reicht eine Funktion „hello“ und eine Property „someText“, welche später in einem Template gebunden werden.
Die dynamische Component könnte wie folgt aussehen.
@Component({ template: dynamicTemplate })
class DynamicComponent {
hello() {
alert("hello dynamic component");
}
someText = "some text";
}
Diese Component integrieren wir in eine Funktion „compileToComponent“, welche als Parameter das Template erwartet.
Zusätzlich wird ein dynamische NgModule erzeugt, welches die dynamische Component deklariert.
@NgModule({
imports: [BrowserModule],
declarations: [DynamicComponent]
})
class DynamicModule { }
Für das Kompilieren eines dynamischen NgModule werden folgende Services benötigt, die in „app.component.ts“ injected werden müssen:
– ViewContainerRef – erstellt eine Referenz zur dynamisch erzeugten Component
– Compiler – kompiliert asynchron das dynamische Module und seine Components
Die Funktion „createDynamicComponent“ soll hier von einem Button-Click getriggered werden und übergibt ein simples Template, welche die oben genannte Funktion „hello“ und das Text Binding „someText“ beinhaltet.
public createDynamicComponent() {
(this.compileToComponent("<div (click)='hello()'>{{someText}}</div>")).then((factory: ComponentFactory<any>) => {
this.cmpRef = this.viewContainerRef.createComponent(factory)
})
}
Template von App abändern, sodass ein Button integriert wird, der die zuvor erstellte Funktion „createDynamicComponent“ aufruft.
template: `<button (click)="createDynamicComponent()">Create dynamic Component</button>`
Wird nun die App neugestartet / refreshed und der Button „Create dynamic Component“ angeklickt, soll genau einmal die „DynamicComponent“ erzeugt und angezeigt werden.
import { Component, OnInit, Input, NgModule, NgModuleFactory, Compiler, ComponentFactory, ViewContainerRef } from'@angular/core';
import { BrowserModule } from'@angular/platform-browser';
@Component({
selector:'my-app',
template:`<button (click)="createDynamicComponent()">Create The Dynamic Component</button>`
})
export class App {
constructor(private viewContainerRef: ViewContainerRef, private compiler: Compiler) {
}
private cmpRef: ComponentRef<any>;
public createDynamicComponent() {
(this.compileToComponent("<div (click)='hello()'>{{someText}}</div>")).then((factory: ComponentFactory<any>) => {
this.cmpRef = this.viewContainerRef.createComponent(factory)
})
}
private compileToComponent(dynamicTemplate: string): Promise<ComponentFactory<any>> {
@Component({ template:dynamicTemplate })
class DynamicComponent {
hello() {
alert("hello dynamic component");
}
someText = "some text";
}
@NgModule({
imports: [BrowserModule],
declarations: [DynamicComponent]
})
class DynamicModule { }
return this.compiler.compileModuleAndAllComponentsAsync(DynamicModule).then(
factory=>factory.componentFactories.find(x=>x.componentType === DynamicComponent)
)
}
}
@NgModule({
imports: [BrowserModule],
declarations: [App],
bootstrap: [App]
})
export class AppModule { }
Ersteller der Webseite MuchaDev. Selbstständiger IT Constultant für Frontend Technologien.