I want to dynamically create a template. This should be used to build a ComponentType
at runtime and place (even replace) it somewhere inside of the ho
Building on top of the answer by Ophir Stern, here is a variant which works with AoT in Angular 4. The only issue I have is I cant inject any services into the DynamicComponent, but I can live with that.
note: I haven't tested with Angular 5.
import { Component, OnInit, Input, NgModule, NgModuleFactory, Compiler, EventEmitter, Output } from '@angular/core';
import { JitCompilerFactory } from '@angular/compiler';
export function createJitCompiler() {
return new JitCompilerFactory([{
useDebug: false,
useJit: true
}]).createCompiler();
}
type Bindings = {
[key: string]: any;
};
@Component({
selector: 'app-compile',
template: `
`,
styleUrls: ['./compile.component.scss'],
providers: [{provide: Compiler, useFactory: createJitCompiler}]
})
export class CompileComponent implements OnInit {
public dynamicComponent: any;
public dynamicModule: NgModuleFactory;
@Input()
public bindings: Bindings = {};
@Input()
public template: string = '';
constructor(private compiler: Compiler) { }
public ngOnInit() {
try {
this.loadDynamicContent();
} catch (err) {
console.log('Error during template parsing: ', err);
}
}
private loadDynamicContent(): void {
this.dynamicComponent = this.createNewComponent(this.template, this.bindings);
this.dynamicModule = this.compiler.compileModuleSync(this.createComponentModule(this.dynamicComponent));
}
private createComponentModule(componentType: any): any {
const runtimeComponentModule = NgModule({
imports: [],
declarations: [
componentType
],
entryComponents: [componentType]
})(class RuntimeComponentModule { });
return runtimeComponentModule;
}
private createNewComponent(template: string, bindings: Bindings): any {
const dynamicComponent = Component({
selector: 'app-dynamic-component',
template: template
})(class DynamicComponent implements OnInit {
public bindings: Bindings;
constructor() { }
public ngOnInit() {
this.bindings = bindings;
}
});
return dynamicComponent;
}
}
Hope this helps.
Cheers!