如何在Angular i18n路由器模块中使用LOCALE_ID

uru*_*ruk 5 routing internationalization angular

我用Angular的i18n设置构建了一个小的Angular应用程序。一切正常,除了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 { }
Run Code Online (Sandbox Code Playgroud)

更新以澄清

在中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/",
                            // ...
                        }
                   }
              }
          }
     }
}
Run Code Online (Sandbox Code Playgroud)

为了一次构建所有应用程序,我输入npm run buildall,它在中执行以下操作package.json

package.json

{
    "name": "my-app",
    // ...
    "scripts": {
        // ...
        "buildall": "for lang in de fr;do ng build --configuration=$lang; done"
    }
}
Run Code Online (Sandbox Code Playgroud)

这样就可以在dist文件夹的子目录中生成所有应用程序。

因此,回到我原来的问题:Exterminator提供的答案不符合我的需求,因为

  • 我在引导时无法设置固定的语言环境
  • 注入LOCALE_ID构造函数为时已晚,因为我需要输入app-routing.module.ts

我希望我能解释得足够多。但是也许我完全误解了一些东西。无论如何,请先感谢您的帮助。我仍在学习,我必须承认一些概念对我来说仍然很模糊。

Ext*_*tor 7

将此添加到app.module

providers: [{provide: LOCALE_ID, useValue: 'fr-FR'}]
Run Code Online (Sandbox Code Playgroud)

然后在需要的地方使用以下方法调用它

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

  constructor(@Inject(LOCALE_ID) locale: string){
    console.log('locale', locale);
  }
Run Code Online (Sandbox Code Playgroud)

你也可以使用这种方法

platformBrowserDynamic([{provide: LOCALE_ID, useValue: 'en-EN'}]).bootstrapModule(AppModule, {providers: [{provide: LOCALE_ID, useValue: 'en-EN'}]});
Run Code Online (Sandbox Code Playgroud)

  • 但这是否意味着在构建应用程序时,LOCALE_ID 将始终为“fr-FR”? (3认同)

Ang*_*rai 3

我有同样的问题,这就是我解决它的方法。

我创建了一个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";
Run Code Online (Sandbox Code Playgroud)

我在 my 中使用了上述常量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
    }
  ],
  ...
Run Code Online (Sandbox Code Playgroud)

现在我需要一个在构建开始之前运行的小脚本,它将在文件中设置本地 ID app-locale.ts。所以我编写了这个小节点脚本并将其放在单独的“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);
Run Code Online (Sandbox Code Playgroud)

接下来,我将继续更改我的设置package.json以包含此设置区域设置 ID。

包.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"
  }
....
Run Code Online (Sandbox Code Playgroud)

我使用的是@ngx-i18nsupportxliffmerge的一部分。这有助于我避免每次提取字符串时覆盖以前提取和翻译的字符串。

因此,现在每当我为所有支持的区域设置构建应用程序时,LOCALE_ID 都会得到适当的设置。我确信一定有其他方法可以解决这个问题,但这就是我解决它的方法。