动态创建其他模块的组件

ome*_*per 5 javascript typescript angular2-services angular

我需要一个全局模态开启服务,可以从任何模块创建动态组件.我有多个模块,每个模块都有模态组件.我简化了我的项目结构:

AppModule  
     ---ModalOpenerService
        --ModalTemplate
     ---AModule
            ---ModalComponent1
            ---ModalComponent2
            ---SimpleComponent
     ---BModule
            ---ModalComponent3
            ---ModalComponent4
Run Code Online (Sandbox Code Playgroud)

模态开启者服务有这样的方法:

@ViewChild('modalContainer', {read: ViewContainerRef}) modalContainer;

showModal(component: Type<any>,data?:any){
    let componentFactory = this.resolver.resolveComponentFactory(component);
    this.modalContainer.createComponent(componentFactory );
}
Run Code Online (Sandbox Code Playgroud)

我希望我的ModalOpenerService能够创建任何模态组件并显示它.但问题是模态组件属于不同的模块,模态开启器无法在其注入器的组件工厂列表中找到它们.

No component factory found for ModalComponent1. Did you add it to @NgModule.entryComponents
Run Code Online (Sandbox Code Playgroud)

显然,ModalComponent1不是AppModule的成员.

我可以通过将工厂方法作为参数而不是像下面这样的组件类型来打开模态:

 //In SimpleComponent, I call my ModalOpenerService to open modal1. Because
 //the simpleComponent's parent injector (AModule's injector) can find Modal1,
 //this.resolver can resolve Modal1.
showModal1(){
   this.modalOpenerService.showModal(this.resolver.resolveComponentFactory(ModalComponent1));
}
Run Code Online (Sandbox Code Playgroud)

在ModalOpenerService中

@ViewChild('modalContainer', {read: ViewContainerRef}) modalContainer;

showModal(factory:ComponentFactory<any>, data?:any){
    this.modalContainer.createComponent(factory);
}
Run Code Online (Sandbox Code Playgroud)

因此,模块创建自己的组件,并且能够在其entryComponents阵列中找到组件.

我们还有一个问题,因为在AppModule范围内创建的任何模态组件,如果我想从模态中显示另一个模态,那么AppModule注入器仍然无法找到它.

一种解决方案可以是将所有模态放入相同的模块中,ModalOpenerService但我希望所有模态都在自己的模块中.

任何结构设计建议也欢迎

Ara*_*vam 0

您需要将 ModalOpenerService 作为单独的模块

    export class ModelModule {
    static WithComponents(components: Array<Type<any>>): Array<any> {
        return {
            ngModule: ModelModule,
            providers: [
                { provide: ANALYZE_FOR_ENTRY_COMPONENTS, useValue: components, multi: true }
            ]
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

从 AModule 和 BModule 中,您可以包含一个 ModelModule,如下所示

    @NgModule({
    imports: [BrowserModule, ModelModule.WithComponents([ModalComponent1, ModalComponent2])],
    declarations: [AppComponent, ModalComponent1, ModalComponent2],
    bootstrap: [AppComponent],
    providers: []
})
export class AModule { }
Run Code Online (Sandbox Code Playgroud)