web-dev-qa-db-fra.com

Chargement différé et définition de LOCALE_ID lors de l'exécution à partir d'une API dans Angular 8 application au démarrage

Nous avons une approche pour le chargement paresseux et la définition de LOCALE_ID de l'application Angular à partir de l'API (en chargeant les données du profil utilisateur lors du démarrage). Cela a bien fonctionné sur Angular 7 mais quand j'ai mis à niveau vers Angular 8, cela a cessé de fonctionner. Lorsque la localeFactory est appelée (voir ci-dessous), la localeService.getLocale() n'est pas définie, elle n'a pas encore été initialisée. Nous l'initialisons dans un SharedResolver qui est dans un SharedModule qui est inclus dans les importations du AppModule. Quelle est la bonne approche pour ce faire dans Angular 8? Je n'ai rien vu de spécifique dans la documentation des changements, donc je suppose que c'est quelque chose indirect. Avez-vous des commentaires sur l'approche à adopter ici? Merci

Veuillez consulter le code correspondant ci-dessous:

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-resolution.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);
15
Botond Béres

Ce que nous faisons dans notre projet, c'est que nous avons en fait des modules chargés en lazylé pour chaque mutation (lang) ou "marché". Cela signifie que vous utilisez Angular routage et injection de dépendances pour séparer les éléments liés à i18n à <lang>.module.ts donc vous en avez un pour chacun et toutes les choses liées au "site" sont traitées dans site.module.ts qui contient réellement l'application elle-même

Vous pouvez voir la solution ici (mais elle n'inclut pas le LOCALE_ID fournir, mais vous pouvez facilement l'ajouter ici)

https://stackblitz.com/github/vmasek/angular-typed-translations-demo


J'ai écrit un article de blog sur cette approche alternative i18n et en tapant les traductions. Vous pouvez en savoir plus à ce sujet ici https://blog.angularindepth.com/angular-typed-translations-29353f0a60bc

0
Vojtech