首页 > 解决方案 > 在库模块中使用 config (forRoot) 加载第三方模块

问题描述

案子:

因此,当我的应用程序至少包含三个主要项目和它们之间的一个共享库(全部通过 cli@ng7 创建)时,我就遇到了这种情况。事情是:这个库导入其他第三方库并使用与我的 SharedLibrary 相同的 forRoot 方法

@NgModule({
    imports: [
        CommonModule,
        FormsModule,
        AgmCoreModule.forRoot({ apiKey: 'some-api-key' })
    ],
    declarations: [
        HeaderComponent,
    ],
    exports: [
        CommonModule,
        FormsModule,
        AgmCoreModule,
        HeaderComponent,
    ]
})
export class SharedLibraryModule {
    static forRoot(
        config: SharedLibraryConfig = new SharedLibraryConfig()
    ): ModuleWithProviders {
        return {
            ngModule: SharedLibraryModule,
            providers: [
                SharedLibraryService,
                {
                    provide: SharedConfigToken,
                    useValue: config
                }
            ]
        };
    }
}

问题

所以基本上上面是我的 SharedLibraryModule (S),它由我的主机项目 (H) (应用程序) 通过SharedLibraryModule.forRoot() 我需要将值从主机应用程序传递到 AgmCoreModule.forRoot({ apiKey: 'some-api-key' }) // <- here

( H -> S -> 3rdparty 模块)

...到目前为止,我想出了两个解决方案,第一个部分有效,第二个无效

解决方案#1

我想这个很hacky。主要思想是从配置参数中获取值并用它修改类体。所以基本上它是在装饰之后但在实例创建之前:

// it's poc/draft so don't ask about quality please :)

export class SharedLibraryModule {
    static forRoot(
        config: SharedLibraryConfig = new SharedLibraryConfig()
    ): ModuleWithProviders {
        const module = SharedLibraryModule['decorators'][0].args[0] as NgModule;
        const agm = module.imports.find(
            item => item['ngModule'] && item['ngModule'].name === 'AgmCoreModule'
        );
        const agmConf = agm['providers'].find(
            item => item && item.useValue && item.useValue.apiKey
        );
        agmConf.useValue.apiKey = 'other value';
        return {
            ngModule: SharedLibraryModule,
            providers: [
                SharedLibraryService,
                {
                    provide: SharedConfigToken,
                    useValue: config
                }
            ]
        };
    }
}

问题:实际上它有效,但没有在产品中测试它。我不知道它是否适用于服务和拦截器,因为我也需要提供一些。我相信这是一种 hacky 方法,如果我错了,请纠正我(我想我需要在这里注入更多角度的方式。

解决方案#2

它现在不起作用 - 但想法是在返回时将所有内容包装在函数中(创建某种工厂)它创建模块并传递给AgmCoreModule.forRoot({ apiKey: 'some-api-key' })特定参数

export const SHARED_MODULE = (
    CONFIG: SharedLibraryConfig = new SharedLibraryConfig()
): ModuleWithProviders => {
    @NgModule({
        imports: [
            CommonModule,
            FormsModule,
            AgmCoreModule.forRoot({ apiKey: 'some-api-key' })
        ],
        declarations: [HeaderComponent],
        exports: [CommonModule, FormsModule, AgmCoreModule, HeaderComponent]
    })
    export class SharedLibraryModule {
        static forRoot(
            config: SharedLibraryConfig = new SharedLibraryConfig()
        ): ModuleWithProviders {
            return {
                ngModule: SharedLibraryModule,
                providers: [
                    SharedLibraryService,
                    {
                        provide: SharedConfigToken,
                        useValue: config
                    }
                ]
            };
        }
    }
}

问题:这实际上完全不起作用。我不认为可以像这样使用类装饰器。编译时的 webpack 说找不到该组件。

标签: angulartypescript

解决方案


推荐阅读