Angular2:多个模块中的一个模块实例
Posted
技术标签:
【中文标题】Angular2:多个模块中的一个模块实例【英文标题】:Angular2: One instance of module in multiple modules 【发布时间】:2017-05-05 18:23:14 【问题描述】:让我们以ng2-translate
插件为例。
我有根AppModule
,还有孩子TopPanelModule
和PagesModule
。
我为AppModule
配置了ng2-translate
。
@NgModule(
imports: [TranslateModule.forRoot(
provide: TranslateLoader,
useFactory: (http: Http) => new TranslateStaticLoader(http, '/assets/i18n', '.json'),
deps: [Http]
)],
exports: []
)
export class AppModule
constructor(translateService: TranslateService)
在AppComponent
中,我为TranslateModule
设置语言和基本配置。
@Component(...)
export class AppComponent
constructor(translateService: TranslateService)
translateService.addLangs(["en", "fr"]);
translateService.setDefaultLang('fr');
const browserLang = 'fr';
translateService.use(browserLang.match(/en|fr/) ? browserLang : 'en');
然后我尝试在子模块组件中使用TranslateModule
- TopPanelComponent
、PagesComponent
。它不起作用。管道不存在错误,没有翻译等。
为了解决这个问题,我创建了一个单独的模块MyTranslateModule
,在上面配置TranslateModule
,并在我的PagesModule
和TopPanelModule
中使用这个模块。
@NgModule(
imports: [TranslateModule.forRoot(
provide: TranslateLoader,
useFactory: (http: Http) => new TranslateStaticLoader(http, '/assets/i18n', '.json'),
deps: [Http]
)],
exports: [TranslateModule]
)
export class MyTranslateModule
constructor(translateService: TranslateService)
translateService.addLangs(["en", "fr"]);
translateService.setDefaultLang('fr');
const browserLang = 'fr';
translateService.use(browserLang.match(/en|fr/) ? browserLang : 'en');
console.log('AdminTrModule: calling');
和
@NgModule(
imports: [MyTranslateModule]
)
export class PagesModule
@NgModule(
imports: [MyTranslateModule]
)
export class TopPanelModule
这是重要的部分。它有效!但我认为它创建了两个 TranslateModule 实例,因此,当我通过调用 TopComponent
translateService.use('en')
更改翻译语言时,它会更改 TopPanelModule
中的语言,但不会更改 PagesModule
中的语言。
【问题讨论】:
你在使用延迟加载吗? @GünterZöchbauer,如果我知道的话,angular2 默认使用延迟加载。 不,当你在路由中使用loadChildren
时会使用延迟加载。
这就是导致生成多个实例的原因。默认情况下,所有导入模块的所有提供程序都注册在应用程序根范围内,但延迟加载的模块有自己的根范围(这是应用程序根范围的子范围)。当来自延迟加载模块的组件或服务注入一些服务并且延迟加载模块让它从那里注册一个实例时,只有当延迟加载模块没有提供程序 DI 检查应用程序根范围时。所有请求相同依赖项的非延迟加载模块都从应用根目录获取一个
检查angular.io/docs/ts/latest/guide/ngmodule.html。我从来没有深入探讨过如何确保延迟加载模块的服务在应用程序根范围内注册,但我想这是可能的。还要检查底部的链接(angular.io/docs/ts/latest/cookbook/ngmodule-faq.html)
【参考方案1】:
你需要在模块'MyTranslateModule'中定义一个forRoot函数
export class MyTranslateModule
static forRoot(): ModuleWithProviders
return
ngModule: MyTranslateModule ,
providers: [TranslateService,TRANSLATION_PROVIDERS]
;
然后在 appModule 中导入 MyTranslateModule 如下
@NgModule(
bootstrap: [App],
declarations: [
App
],
imports: [ // import Angular's modules
BrowserModule,
MyTranslateModule.forRoot(),
PagesModule,
TopPanelModule
],
providers: [ // expose our Services and Providers into Angular's dependency ]
)
在这种情况下,翻译服务将被创建为单例“应用程序中的一个实例”
【讨论】:
以上是关于Angular2:多个模块中的一个模块实例的主要内容,如果未能解决你的问题,请参考以下文章
Angular 2 - 多个模块中的管道重用 - 未找到错误或重复定义