web-dev-qa-db-fra.com

Comment utiliser LOCALE_ID dans Angular i18n Router Module

Je construis un petit Angular Application avec la configuration i18n d'Angular. Tout fonctionne correctement, sauf pour les traductions des chemins d'URL et des limaces. J'ai essayé une solution possible en fournissant un module de routage par langue (comme décrit ici), mais cela n'a pas fonctionné.

J'ai pensé que je pouvais faire quelque chose comme ceci, mais je n'arrive pas à savoir où injecter LOCALE_ID:

app-routing.module.ts

import { LOCALE_ID, NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { MainComponent } from './main/main.component';

const i18nRoutes = {
    de: {
        main: 'inhalte',
        // ...
    }, 
    fr: {
        main: 'contenu',
        // ...
    }
}

const currentLanguage = i18nRoutes[ LOCALE_ID ]; // <-- Apparently not working, since I have to inject LOCALE_ID. But where?

const routes: Routes = [
    {
        path: '',
        redirectTo: currentLanguage.main,
        pathMatch: 'full'
    },
    {
        path: currentLanguage.main + '/:key',
        component: MainComponent
    }
    // ...
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Mise à jour pour clarification

dans angular.json, J'ai défini des configurations pour le processus de construction dans chaque langue (tiré de ici , avec une vue des modifications pour 2018)

angular.json

{
    // ...
    "projects": {
        "my-app": {
            // ...
            "architect": {
                "build": {
                    // ...
                    "configurations": {
                        // ...
                        "de": {
                            "i18nFile": "src/i18n/de.xliff",
                            "outputPath": "dist/de",
                            "i18nFormat": "xlf",
                            "i18nLocale": "de",
                            "baseHref": "/de/"
                            // ...
                        },
                        "fr": {
                            "i18nFile": "src/i18n/fr.xliff",
                            "outputPath": "dist/fr",
                            "i18nFormat": "xlf",
                            "i18nLocale": "fr",                            
                            "baseHref": "/fr/",
                            // ...
                        }
                   }
              }
          }
     }
}

Pour créer toutes les applications à la fois, j'entre alors npm run buildall, qui exécute ce qui suit dans package.json:

package.json

{
    "name": "my-app",
    // ...
    "scripts": {
        // ...
        "buildall": "for lang in de fr;do ng build --configuration=$lang; done"
    }
}

qui génère toutes les applications dans un sous-répertoire du dossier dist très bien.

Donc, pour revenir à ma question d'origine: La réponse fournie par Exterminator ne correspond pas à mes besoins, car

  • Je ne peux pas définir de paramètres régionaux fixes lors du démarrage
  • Injection LOCALE_ID dans le constructeur est trop tard car j'ai besoin de la valeur dans app-routing.module.ts

J'espère avoir suffisamment expliqué. Mais peut-être que j'ai complètement mal compris quelque chose. En tout cas, merci d'avance pour toute aide. J'apprends toujours et je dois admettre que quelques concepts me sont encore flous.

5
uruk

J'ai eu le même problème exact et c'est ainsi que je l'ai résolu.

J'ai créé un app-locale.ts fichier qui n'avait qu'une seule constante qu'il exporte et qui peut ensuite être utilisé pour le fournisseur LOCALE_ID pour définir l'ID de paramètres régionaux.

src/app/app-locale.ts

/*
    WARNING: This file is to help facilitate the auotmation of the build
    process. In order to set the locale during development, change
    the value by hand to the target locale. If the file name or 
    location is changed make sure to update the build scripts
    accordingly.
*/ 
export const APP_LOCALE_ID:string = "es-es";

J'ai utilisé la constante ci-dessus dans mon app.module.ts pour fournir le LOCALE_ID.

src/app/app.module.ts

import { LOCALE_ID, NgModule, TRANSLATIONS, TRANSLATIONS_FORMAT } from "@angular/core";
import { APP_LOCALE_ID } from './app-locale';
...
providers: [{
      provide: TRANSLATIONS_FORMAT,
      useValue: "xlf"
    }, { 
      provide: TRANSLATIONS, 
      useFactory: (locale) => {
        locale = locale || 'en-US'; 
        return require(`raw-loader!../locale/messages.${locale}.xlf`);
      },
      deps: [LOCALE_ID] 
    }, {
      provide: LOCALE_ID,
      useValue: APP_LOCALE_ID
    }
  ],
  ...

Maintenant, j'ai besoin d'un petit script qui s'exécuterait avant le début de la construction qui définira l'ID local dans le fichier app-locale.ts. J'ai donc écrit ce petit script de nœud et l'ai mis dans un dossier "scripts" séparé.

scripts/set-app-locale.js

const fs = require('fs');
const argv = require('minimist')(process.argv.slice(2));

var version = '0.0.1',
    appLocale = "en-US",
    appLocaleFile = "./src/app/app-locale.ts",
    help = `
Set the static locale for the app.
Usage: node <path>set-app-locale.js [options]

Options:
  --version         Show version number                                  [boolean]
  --help, -h        Show help                                            [boolean]
  --app-locale      Target locale id                                     [string]
  --app-locale-file                                                      [string]
                    Path and name of app-locale that contains only one constant which
                    is a const string that holds the locale value. 
                    [default: "${__dirname}/src/app/app-locale.ts"]   `;

var setArgs = function(){
    if (argv.version){
        console.log(version);
        return false;
    }
    if (argv.h || argv.help){
        console.log(help);
        return false;
    }
    appLocale = argv["app-locale"] || appLocale;
    appLocaleFile = argv["app-locale-file"] || appLocaleFile;
    return true;
}
var setLocale = function(locale){
    var fileData = 
`/*
    WARNING: This file is to help facilitate the automation of the build
    process. In order to set the locale during development, change
    the value by hand to the target locale. If the file name or 
    location is changed make sure to update the build scripts
    accordingly.
*/ 
export const APP_LOCALE_ID:string = "${locale}";`;
    fs.writeFile(appLocaleFile, fileData, function(err) {
        if(err) {
            return console.log(err);
        }
        console.log(`App locale changed to ${locale}`);
    }); 
}

setArgs() && setLocale(appLocale);

Ensuite, j'irais de l'avant et changerais mon package.json pour l'inclure afin de définir l'ID de paramètres régionaux.

package.json

....
"config": {"locales": "en-US es-es"},
  "scripts": {
    ...
    "i18n-build": "for lang in $npm_package_config_locales; do node ./scripts/set-app-locale.js --app-locale=$lang && ng build --prod --configuration=$lang; done"
  }
....

J'utilise xliffmerge qui fait partie de @ ngx-i18nsupport . Cela m'aide à éviter d'écraser les chaînes précédemment extraites et traduites à chaque fois que j'extrais des chaînes.

Alors maintenant, chaque fois que je crée l'application pour tous les paramètres régionaux pris en charge, LOCALE_ID est défini de manière appropriée. Je suis sûr qu'il doit y avoir d'autres façons de résoudre ce problème, mais c'est ainsi que je l'ai résolu.

0
Angry Samurai

ajoutez ceci à l'app.module

providers: [{provide: LOCALE_ID, useValue: 'fr-FR'}]

puis appelez-le en utilisant la méthode suivante où vous voulez

import {LOCALE_ID} from '@angular/core';

  constructor(@Inject(LOCALE_ID) locale: string){
    console.log('locale', locale);
  }

vous pouvez également utiliser cette méthode

platformBrowserDynamic([{provide: LOCALE_ID, useValue: 'en-EN'}]).bootstrapModule(AppModule, {providers: [{provide: LOCALE_ID, useValue: 'en-EN'}]});
8
Exterminator