APIからAngularアプリケーションのLOCALE_IDを遅延読み込みして設定する方法があります(起動時にユーザープロファイルデータを読み込むことにより)。これはAngular 7では問題なく機能しましたが、Angular 8にアップグレードすると機能しなくなりました。 localeFactoryが呼び出されたとき(以下を参照)、localeService.getLocale()
は未定義であり、まだ初期化されていません。 SharedResolver
のインポートに含まれるSharedModule
にあるAppModule
で初期化します。 Angular 8でこれを行うための正しいアプローチは何ですか?変更のドキュメントにこれに固有のものは何も見られなかったので、それは間接的なものだと思います。ここで私が取るべきアプローチについて何か意見はありますか?ありがとう
以下の関連コードを参照してください:
app.module.ts
export function localeFactory(localeService: LocaleService) {
console.log('locale factory called');
// This is `undefined` here now for some reason
console.log(localeService.getLocale());
return localeService.getLocale() || 'en';
}
...
const APP_LOCALE_ID = {
provide: LOCALE_ID,
deps: [LocaleService],
useFactory: localeFactory
};
@NgModule({
imports: [
BrowserModule,
FormsModule,
HttpClientModule,
BrowserAnimationsModule,
AppRoutingModule,
SharedModule.forRoot(), // <- in this module we have the SharedResolver
AccountModule,
ApiModule,
GenesysSubprojectModule
],
declarations: [AppComponent],
providers: [
AppRouteGuard,
BreadcrumbService,
{
provide: APP_INITIALIZER,
useFactory: appInitializerFactory,
deps: [PlatformLocation, BootstrapService],
multi: true
},
{ provide: ErrorHandler, useClass: GlobalErrorHandler },
AppRouteGuard,
BreadcrumbService,
// TODO - This doesn't work anymore!
APP_LOCALE_ID
],
bootstrap: [AppComponent]
})
export class AppModule {}
shared-resolve.ts
export class SharedResolve implements Resolve<any> {
...
resolve(route: ActivatedRouteSnapshot) {
...
const observables = forkJoin(
this.authService.getPermissions(),
this.authService.getCurrentProfileFromApi(),
this.languageApi.getActiveLanguages(), // TODO - cache
this.tenantSettingsApi.getLogo(logoLastModificationTime),
this.dashboardApi.getDashboardSettings(),
this.reportApi.getReportSettings(),
this.publicSettingsApi.getSettings(),
this.tenantSettingsApi.getInitializationSettings()
) as Observable<any[]>;
return observables
.pipe(
flatMap(result => {
...
const profile: CurrentUserProfileExtEditDto = result[1];
...
const languageName =
profile.languageName || navigator.language; // browser default language
console.log('Set locale to languageName=' + languageName);
this.storageService.setLocale(languageName);
this.localeService.setLocale(languageName);
私たちのプロジェクトで行っていることは、実際には各(lang)ミューテーションまたは「マーケット」に対してレイジーロードされたモジュールがあるということです。これは、Angularルーティングと依存性注入を使用して、i18n関連のものを<lang>.module.ts
に分離するため、「サイト」関連のものがすべてsite.module.ts
で処理され、実際にアプリケーション自体を保持します
ここで解決策を見ることができます(ただし、LOCALE_ID
は含まれていませんが、簡単に追加できます)。
https://stackblitz.com/github/vmasek/angular-typed-translations-demo
私はこの代替i18nアプローチと翻訳の入力についてブログ投稿を書きました。詳細はこちら https://blog.angularindepth.com/angular-typed-translations-29353f0a60bc