web-dev-qa-db-ja.com

Angular i18nルーターモジュールでLOCALE_IDを使用する方法

小さなAngular Angularのi18n設定のアプリケーションを構築しています。URLパスとスラッグの翻訳を除いて、すべてが正常に機能していません。言語ごとにルーティングモジュールを提供することで可能な解決策を試しました(ここで説明されています)が、これは機能しませんでした。

私は次のようなことをすることができると思ったが、どこに挿入するかがわかりません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 { }

明確化のための更新

angular.jsonで、ビルドプロセスの構成を各言語で設定しました(2018年のビューを変更して here から取得)

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を挿入するのは遅すぎます

十分に説明していただければ幸いです。 しかし、私は何かを完全に誤解したかもしれません。いずれにせよ、事前に助けをありがとう。私はまだ学んでおり、いくつかの概念がまだぼやけていることを認めなければなりません。

5
uruk

私はまったく同じ問題を抱えていましたが、これが私がそれを解決した方法です。

エクスポートする定数が1つだけのapp-locale.tsファイルを作成しました。このファイルは、LOCALE_IDプロバイダーがロケールIDを設定するために使用できます。

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";

上記の定数をapp.module.tsで使用して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
    }
  ],
  ...

ここで、ビルドが開始する前に実行される小さなスクリプトが必要です。これにより、app-locale.tsファイルにローカルIDが設定されます。そこで、この小さなノードスクリプトを記述して、別の「スクリプト」フォルダに配置しました。

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);

次に、ロケールIDを設定するためにこれを含めるように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"
  }
....

@ ngx-i18nsupport の一部であるxliffmergeを使用します。これは、文字列を抽出するたびに、以前に抽出および翻訳された文字列を上書きしないようにするのに役立ちます。

したがって、サポートされているすべてのロケールのアプリをビルドするたびに、LOCALE_IDが適切に設定されます。この問題を解決する方法は他にもあるはずですが、これが私が解決した方法です。

0
Angry Samurai

これを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'}]});
8
Exterminator