使用库模块

时间:2019-02-08 19:26:05

标签: angular typescript

案例:

因此,当我的应用程序至少包含三个主要项目以及它们之间的一个共享库(都通过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

我认为这是一个很棘手的事情。主要思想是从config参数获取值并使用其修改类主体。因此,基本上是在装饰之后但在实例创建之前:

// 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
                }
            ]
        };
    }
}

问题:实际上它有效,但是并未在产品中对其进行测试。我不知道它是否可以与服务和拦截器一起使用,因为我也需要提供一些服务。我相信这是一种骇人听闻的方法,如果我做错了,请纠正我(我认为我需要在此处注入更多角度。

解决方案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表示找不到该组件。

0 个答案:

没有答案