Trying to generate components on-the-fly (based on this repo)
I am facing an issue: I can generate the html template by reading stored templates using the template
const below and assigning it the htmlTemplate
for a component (here I named it application
), but I can't think of a way to use a stored TypeScript code for the same component named say tsTemplate
. How should I do it?
See code:
import { Component, OnInit, OnDestroy, ComponentRef, ViewChild, ViewContainerRef, Compiler, Injector, NgModuleRef, NgModule } from '@angular/core';
import { ActivatedRoute, Params } from '@angular/router';
import { Application } from '../application.model';
import { ApplicationService } from '../application.service';
@Component({
selector: 'app-app-frame',
templateUrl: './app-frame.component.html',
styleUrls: ['./app-frame.component.css']
})
export class AppFrameComponent implements OnInit, OnDestroy {
@ViewChild('vc', { read: ViewContainerRef }) _container: ViewContainerRef;
application: Application;
appIndex: number;
cmpRef: ComponentRef<any>;
constructor(private route: ActivatedRoute,
private applicationService: ApplicationService,
private _compiler: Compiler, private _injector: Injector, private _m: NgModuleRef<any>
) { }
ngOnInit() {
this.appIndex = +this.route.snapshot.params['id'];
this.application = this.applicationService.getApp(this.appIndex);
this.route.params.subscribe(
(params: Params)=>{
this.appIndex = params['id'];
this.application = this.applicationService.getApp(params['id']);
if(this.cmpRef) {
this.cmpRef.destroy();
}
///// HERE ////////
const template = this.application.htmlTemplate;
const tmpCmp = Component({template: template})(class {});
const tmpModule = NgModule({declarations: [tmpCmp]})(class {});
this._compiler.compileModuleAndAllComponentsAsync(tmpModule)
.then((factories) => {
const f = factories.componentFactories[0];
this.cmpRef = f.create(this._injector, [], null, this._m);
this.cmpRef.instance.name = this.application.name;
this._container.insert(this.cmpRef.hostView);
})
});
}
ngOnDestroy() {
if(this.cmpRef) {
this.cmpRef.destroy();
}
}
}