Angular2 - 更改动态组件/重装模块的模板

时间:2017-04-02 19:34:08

标签: angular

我有一个动态组件,它在运行时接收它的模板,并使用编译器的compileModuleAndAllComponentsSync方法动态编译,来自' @ angular / core'。

这是我用来获取运行时组件的componentFactory的代码(请参阅Plunker获取完整代码,所有有趣的内容都在runtime-content.component.ts中)

private createComponentFactorySync(compiler: Compiler, metadata: Component): ComponentFactory<any> {
    let decoratedCmp = Component(metadata)(RuntimeComponent);

    @NgModule({ imports: [CommonModule], declarations: [decoratedCmp] })
    class RuntimeComponentModule { }

    let module: ModuleWithComponentFactories<any> = compiler.compileModuleAndAllComponentsSync(RuntimeComponentModule);

    return module.componentFactories.find(f => f.componentType === decoratedCmp);
}

enter image description here

一切正常,动态模板在第一次编译时工作正常。但是对于我的用例,我需要能够更改模板并重新编译几次。但是第二次尝试编译时我得到了错误

&#34;类型RuntimeComponent是2个模块声明的一部分:RuntimeComponentModule和RuntimeComponentModule!&#34;

这当然有意义,因为它确实编译成了同一类型的另一个模块。所以我的想法是尝试卸载以前创建的模块,但无法找到任何方法。

任何人都有想法实现我想做的事情?也许通过卸载模块或者以其他方式卸载。我提供了一个工作的plunker来显示问题。按&#39;编译&#39;按钮将编译可以正常工作的动态模板(按下&#39; Inc&#39;按钮增加值)。再次按下编译将引发上述错误,组件将停止工作。

Plunker

2 个答案:

答案 0 :(得分:1)

我会使用compiler.clearCacheFor方法解决您的问题:

compiler.clearCacheFor(decoratedCmp);

<强> Plunker Example

另见

答案 1 :(得分:0)

另一个解决方案是为每个新组件声明一个新类,并且每次都不要重复使用相同的RuntimeComponent

protected createNewComponent(tmpl: string) {

    @Component({
        selector: `runtime-component-dynamic`,
        template: tmpl
    })
    class RuntimeComponent {
        name: string = 'Tim Jelly';
        value: number = 42;

        incValue() {
            this.value++;
        }
    }

    return RuntimeComponent;
}

请参阅Plunker