Angular2:多个模块中的一个模块实例

Angular2:多个模块中的一个模块实例,angular,typescript,module,components,Angular,Typescript,Module,Components,让我们为ng2translate插件做个例子 我有根AppModule,子TopPanelModule和PagesModule @NgModule({ imports: [TranslateModule.forRoot({ provide: TranslateLoader, useFactory: (http: Http) => new TranslateStaticLoader(http, '/assets/i18n', '.json'), deps: [Ht

让我们为
ng2translate
插件做个例子

我有根
AppModule
,子
TopPanelModule
PagesModule

@NgModule({
  imports: [TranslateModule.forRoot({
    provide: TranslateLoader,
    useFactory: (http: Http) => new TranslateStaticLoader(http, '/assets/i18n', '.json'),
    deps: [Http]
  })],
  exports: []
})
export class AppModule {
  constructor(translateService: TranslateService) {    
  }
}
@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');    
  }
}
@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');
  }
}

我为
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) {    
  }
}
@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');    
  }
}
@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');
  }
}

AppComponent
中,我设置了
TranslateModule
的语言和基本配置

@NgModule({
  imports: [TranslateModule.forRoot({
    provide: TranslateLoader,
    useFactory: (http: Http) => new TranslateStaticLoader(http, '/assets/i18n', '.json'),
    deps: [Http]
  })],
  exports: []
})
export class AppModule {
  constructor(translateService: TranslateService) {    
  }
}
@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');    
  }
}
@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');
  }
}

然后我尝试在子模块组件中使用
TranslateModule
PagesComponent
。没用。管道不存在错误、无翻译等


为了解决此问题,我创建了一个单独的模块
MyTranslateModule
,在其上配置
TranslateModule
,并在my
PagesModule
TopPanelModule
中使用此模块

@NgModule({
  imports: [TranslateModule.forRoot({
    provide: TranslateLoader,
    useFactory: (http: Http) => new TranslateStaticLoader(http, '/assets/i18n', '.json'),
    deps: [Http]
  })],
  exports: []
})
export class AppModule {
  constructor(translateService: TranslateService) {    
  }
}
@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');    
  }
}
@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');
  }
}



这是一个重要的部分。它起作用了!但我认为它创建了TranslateModule的两个实例,因此,当我通过调用
TopComponent
translateService.use('en')
)来更改TranslateModule的Translate语言时,它会更改
TopPanelModule
中的语言,而不是
PagesModule
中的语言,您需要在模块“MyTranslateModule”中定义一个forRoot函数

@NgModule({
  imports: [TranslateModule.forRoot({
    provide: TranslateLoader,
    useFactory: (http: Http) => new TranslateStaticLoader(http, '/assets/i18n', '.json'),
    deps: [Http]
  })],
  exports: []
})
export class AppModule {
  constructor(translateService: TranslateService) {    
  }
}
@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');    
  }
}
@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');
  }
}
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 ]
})

在这种情况下,translate服务将被创建为singleton“应用程序中的一个实例”

您是否使用延迟加载?@GünterZöchbauer,如果我知道正确的话,angular2默认使用延迟加载。不,当您在routes中使用
loadChildren
时使用延迟加载。这就是导致生成多个实例的原因。默认情况下,来自所有导入模块的所有提供程序都在应用程序根作用域中注册,但延迟加载的模块会获得自己的根作用域(即应用程序根作用域的子作用域)。当来自延迟加载模块的组件或服务注入某些服务,并且延迟加载模块让它注册来自该模块的实例时,只有在延迟加载模块没有提供程序DI的情况下,才会使用应用程序根作用域进行检查。所有请求相同依赖项的非惰性加载模块都从应用程序根检查中获得一个。我从未深入讨论过如何确保惰性加载模块的服务在应用程序根作用域中注册,但我想这是可能的。同时检查底部的链接()