How can I use/create dynamic template to compile dynamic Component with Angular 2.0?

后端 未结 15 1879
忘掉有多难
忘掉有多难 2020-11-21 05:14

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

15条回答
  •  礼貌的吻别
    2020-11-21 05:56

    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!

提交回复
热议问题