Angular NgModule嵌套forRoot

Angular NgModule嵌套forRoot,angular,typescript,Angular,Typescript,考虑到有一个模块 @NgModule({ imports: [ Ng2Webstorage.forRoot({ prefix: 'SOME_PREFIX' }), FooModule.forRoot(...), BarModule, ], exports: [ Ng2Webstorage, FooModule, BarModule, ] }) class Feature

考虑到有一个模块

@NgModule({
    imports: [
        Ng2Webstorage.forRoot({ prefix: 'SOME_PREFIX' }),
        FooModule.forRoot(...),
        BarModule,
    ],
    exports: [
        Ng2Webstorage,
        FooModule,
        BarModule,
    ]
})
class FeatureModule {
    static forRoot(config): ModuleWithProviders {
        return {
            ngModule: FeatureModule,
            providers: [...]
        };
    }
}
它如何将
前缀
动态传递给
Ng2Webstorage.forRoot
?比如:

@NgModule({
    imports: [
        BarModule,
    ],
    exports: [
        Ng2Webstorage,
        FooModule,
        BarModule,
    ]
})
class FeatureModule {
    static forRoot(config): ModuleWithProviders {
        return {
            ngModule: FeatureModule,
            imports: [
                Ng2Webstorage.forRoot({ prefix: config.name }),
                FooModule.forRoot(config.foo)
            ],
            providers: [...]
        };
    }
}

...
imports: [FeatureModule.forRoot({ name: `ANOTHER_PREFIX` }), ...]
...
是否可以嵌套
forRoot
调用


看起来,
ModuleWithProviders
不接受
导入

是的,您是对的。我们无法将
imports
传递给
ModuleWithProviders
import

以下是angular如何从此类导入中收集数据:

} else if (importedType && importedType.ngModule) {
    const moduleWithProviders: ModuleWithProviders = importedType;
    importedModuleType = moduleWithProviders.ngModule;
    if (moduleWithProviders.providers) {
      providers.push(...this._getProvidersMetadata(
          moduleWithProviders.providers, entryComponents,
          `provider for the NgModule '${stringifyType(importedModuleType)}'`, [],
          importedType));
}

我们可以通过在
ModuleWithProviders中传递相同的提供程序来覆盖在中定义的提供程序。提供程序如下所示:

import {Ng2Webstorage, WEBSTORAGE_CONFIG} from 'ngx-webstorage';

@NgModule({
  imports: [
    Ng2Webstorage.forRoot()
  ],
  ...
})
export class FeatureModule {
  static forRoot(config): ModuleWithProviders {
    return {
      ngModule: FeatureModule,
      providers: [
        { provide: WEBSTORAGE_CONFIG, useValue: config }
      ]
    };
  }
}

可以通过在
forRoot()中显式重新定义提供程序来实现。包的其他元素可以按常规方式导入和导出

请注意,我使用它可以轻松地链接多个模块

@NgModule({
    imports: [
        BarModule,
    ],
    exports: [
        Ng2Webstorage,
        FooModule,
        BarModule,
    ]
})
class FeatureModule {
    static forRoot(config): ModuleWithProviders {
        return {
            ngModule: FeatureModule,
            /* Explicitly redefine the providers from imported/exported modules. */
            providers: [].concat(
                Ng2Webstorage.forRoot({ prefix: config.name }).providers,
                FooModule.forRoot(config.foo).providers
            )
        };
    }
}
编辑:

当您使用AOT编译时,上述方法不起作用。相反,对于静态导出函数和类型化参数,请使用以下变通方法,例如
config

export function ng2WebstorageProviders(name: string) {
  return Ng2Webstorage.forRoot({ prefix: name }).providers;
}

export function fooProviders(foo: object) {
  return FooModule.forRoot(foo).providers;
}

@NgModule({
  imports: [
    BarModule,
  ],
  exports: [
    Ng2Webstorage,
    FooModule,
    BarModule,
  ]
})
class FeatureModule {
  static forRoot(config: {name: string, foo: object}): ModuleWithProviders {
    return {
      ngModule: FeatureModule,
      /* Explicitly redefine the providers from imported/exported modules. */
      providers: [
        ...ng2WebstorageProviders(config.name),
        ...fooProviders(config.foo)
      ]
    };
  }
}
供参考:


谢谢,这正是我害怕的,看来这是唯一的办法。这里的缺点是forRoot需要虚拟配置,即使它现在接受未定义的或空的对象,将来也可能中断。