import {
Component,
NgModule,
Injectable,
Compiler,
ViewContainerRef,
ModuleWithProviders,
Type,
} from '@angular/core';
export interface CompileOptions {
template: string;
container: ViewContainerRef;
imports?: Array<Type<any> | ModuleWithProviders | any[]>;
context?: any,
onCompiled?: Function,
onError?: Function;
}
const cache : any = {};
@Injectable()
export class CompileService {
constructor(
private compiler: Compiler,
) {
}
public async compile(opts: CompileOptions) {
try {
const factory = await this.createFactory(opts);
opts.container.clear();
const cmp : any = opts.container.createComponent(factory);
cmp.instance.context = opts.context;
} catch (e) {
if (opts.onError) {
opts.onError(e)
} else {
console.error(e);
}
}
}
private async createFactory(opts: CompileOptions) {
const cacheKey = opts.template;
if (Object.keys(cache).indexOf(cacheKey) > -1) {
return cache[cacheKey];
}
cache[cacheKey] = new Promise(async(resolve) => {
@Component({
template: opts.template
})
class TemplateComponent {
context: any
}
@NgModule({
imports: opts.imports,
declarations: [TemplateComponent]
})
class TemplateModule {
}
const component = await this.compiler.compileModuleAndAllComponentsAsync(TemplateModule);
const factory = component.componentFactories.find((comp) =>
comp.componentType === TemplateComponent
);
if (opts.onCompiled) {
opts.onCompiled(component);
}
cache[cacheKey] = factory;
resolve(factory);
})
return cache[cacheKey];
}
}