Я создаю небольшое приложение Angular с настройкой Angular i18n. Все работает нормально, за исключением переводов URL-адресов и ярлыков. Я попробовал возможное решение с предоставлением модуля маршрутизации для каждого языка (как описано здесь), но это не сработало.

Я думал, что могу сделать что-то вроде следующего, но не могу понять, куда вводить LOCALE_ID:

< STRONG> приложение - 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 { }

Обновление для уточнения

В angular.json я установил конфигурации для процесса сборки на каждом языке (взято из здесь, с обзором изменений на 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/",
                            // ...
                        }
                   }
              }
          }
     }
}

Для создания сразу всех приложений я затем ввожу npm run buildall, который выполняет в package.json следующее:

< Сильный > package.json

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

Который генерирует все приложения в подкаталоге в папке dist нормально.

Итак, возвращаясь к моему первоначальному вопросу: предоставленный ответ Exterminator не соответствует моему потребности, так как

  • Я не могу установить фиксированный языковой стандарт во время начальной загрузки
  • Вводить LOCALE_ID в конструктор слишком поздно, так как мне нужно значение в app-routing.module.ts

Надеюсь, я достаточно объяснил. Но, может быть, я что-то совершенно неправильно понял. В любом случае заранее спасибо за любую помощь. Я все еще учусь и должен признать, что некоторые концепции все еще остаются для меня размытыми.

7
uruk 14 Сен 2018 в 16:42

2 ответа

Лучший ответ

У меня была такая же проблема, и я решил ее вот так.

Я создал файл app-locale.ts, в котором была только одна экспортируемая константа, которую затем можно использовать для поставщика LOCALE_ID для установки идентификатора языкового стандарта.

< Сильный > ЦСИ / приложение / приложение - 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";

Я использовал указанную выше константу в моем app.module.ts, чтобы предоставить LOCALE_ID.

< Сильный > ЦСИ / приложение / 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
    }
  ],
  ...

Теперь мне нужен небольшой скрипт, который будет запускаться перед началом сборки и установит локальный идентификатор в файле app-locale.ts. Итак, я написал этот небольшой сценарий узла и поместил его в отдельную папку «сценариев».

< Сильный > Сценарии / набор - приложение - 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);

Затем я бы пошел дальше и изменил свой package.json, чтобы включить это, чтобы установить идентификатор локали.

< Сильный > 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"
  }
....

Я использую xliffmerge, который является частью @ ngx-i18nsupport . Это помогает мне избежать перезаписи ранее извлеченных и переведенных строк каждый раз, когда я извлекаю строки.

Итак, теперь, когда я создаю приложение для всех поддерживаемых языков, LOCALE_ID устанавливается соответствующим образом. Я уверен, что должны быть другие способы решения этой проблемы, но я решил ее так.

0
Angry Samurai 13 Дек 2018 в 01:33

Добавьте это в app.module

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

Затем вызовите его, используя следующий метод, где хотите

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

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

Также вы можете использовать этот метод

platformBrowserDynamic([{provide: LOCALE_ID, useValue: 'en-EN'}]).bootstrapModule(AppModule, {providers: [{provide: LOCALE_ID, useValue: 'en-EN'}]});
10
Exterminator 14 Сен 2018 в 13:54