UNPKG

2.62 kBPlain TextView Raw
1import {
2 Component,
3 NgModule,
4 ComponentFactoryResolver,
5 Input,
6 Injector,
7 ComponentRef,
8 ViewContainerRef,
9 Compiler,
10} from '@angular/core';
11
12import { CommonModule } from '@angular/common';
13
14@Component({
15 selector: 'templation',
16 template: `<div></div>`
17})
18export class TemplationComponent {
19 @Input() imports: [] = null;
20 @Input() template: string = null;
21 @Input() component: any;
22 constructor(
23 private vr: ViewContainerRef,
24 private cfr: ComponentFactoryResolver,
25 private compiler: Compiler
26 ) { }
27
28 ngOnInit() {
29 this.renderComponent();
30 }
31
32 renderComponent() {
33 const hasTemplate = !!this.template;
34 if (!this.component || !hasTemplate) return false;
35 const templatedComponent = this.returnTemplatedComponent();
36 const templationModule = this.returnTemplationModule({ templatedComponent });
37
38 this.compiler.compileModuleAndAllComponentsAsync(templationModule)
39 .then(factory => {
40 const compFactory = factory.componentFactories.find(x => x.componentType === templatedComponent);
41 const cmpRef = this.vr.createComponent(compFactory, 0);
42 });
43 }
44
45 // will be used to get dependecies from constructor of
46 // parent class
47 private getDeps(func) {
48 // First match everything inside the function argument parens.
49 const args = func.toString().match(/function\s.*?\(([^)]*)\)/)[1];
50 // Split the arguments string into an array comma delimited.
51 return args.split(',').map(function(arg) {
52 // Ensure no inline comments are parsed and trim the whitespace.
53 return arg.replace(/\/\*.*\*\//, '').trim();
54 }).filter(function(arg) {
55 // Ensure no undefined values are added.
56 return arg;
57 });
58 }
59
60 returnTemplatedComponent() {
61 const componentDeps = this.getDeps(this.component.constructor);
62 const diParams = componentDeps.map(dep => this.component[dep]);
63
64 const componentMeta = {
65 selector: 'templatedComponent',
66 template: this.template,
67 };
68
69 @Component(componentMeta)
70 class TemplatedComponent extends this.component {
71 constructor() {
72 super(diParams);
73 }
74 }
75
76 const componentInstance = new this.component(diParams);
77 const componentKeys = Object.keys(componentInstance);
78 componentKeys.map(key => TemplatedComponent[key] = componentInstance[key]);
79
80 return TemplatedComponent;
81 }
82
83 returnTemplationModule({ templatedComponent }) {
84 const dynamicImports = this.imports;
85 @NgModule({
86 imports: dynamicImports,
87 declarations: [templatedComponent]
88 })
89 class TemplationModule {}
90 return TemplationModule;
91 }
92
93}