1 | import {
|
2 | Component,
|
3 | NgModule,
|
4 | ComponentFactoryResolver,
|
5 | Input,
|
6 | Injector,
|
7 | ComponentRef,
|
8 | ViewContainerRef,
|
9 | Compiler,
|
10 | } from '@angular/core';
|
11 |
|
12 | import { CommonModule } from '@angular/common';
|
13 |
|
14 | @Component({
|
15 | selector: 'templation',
|
16 | template: `<div></div>`
|
17 | })
|
18 | export 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 |
|
46 |
|
47 | private getDeps(func) {
|
48 |
|
49 | const args = func.toString().match(/function\s.*?\(([^)]*)\)/)[1];
|
50 |
|
51 | return args.split(',').map(function(arg) {
|
52 |
|
53 | return arg.replace(/\/\*.*\*\//, '').trim();
|
54 | }).filter(function(arg) {
|
55 |
|
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 | }
|