【问题标题】:How To Use LOCALE_ID In Angular i18n Router Module如何在 Angular i18n 路由器模块中使用 LOCALE_ID
【发布时间】:2019-02-19 08:14:24
【问题描述】:

我正在使用 Angular 的 i18n 设置构建一个小型 Angular 应用程序。一切正常,除了 url 路径和 slug 的翻译。我尝试了一种可能的解决方案,为每种语言提供一个路由模块(如此处所述),但这不起作用。

我以为我可以做类似以下的事情,但我不知道在哪里注入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 中,我为每种语言的构建过程设置了配置(取自here,查看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文件夹的子目录中生成所有应用程序就好了。

所以,回到我原来的问题:提供的answer by Exterminator 不符合我的需求,因为

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

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

【问题讨论】:

    标签: angular routing internationalization


    【解决方案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”文件夹中。

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

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

    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 都会得到适当的设置。我相信肯定有其他方法可以解决这个问题,但我就是这样解决的。

    【讨论】:

      【解决方案2】:

      将此添加到 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'}]});
      

      【讨论】:

      • 但这不是意味着在构建应用程序时,LOCALE_ID 将始终为“fr-FR”吗?
      • 更多参考请查看Internationalization (i18n)
      • 我不想设置它,而是在构建应用程序时使用提供的值。
      • 我分享了这两个东西,如何设置和使用它。你可以导入它并按照我定义的方式使用它
      • 更新了我的问题以便澄清
      猜你喜欢
      • 2017-09-18
      • 2019-09-11
      • 2020-06-08
      • 2020-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-13
      • 2016-12-28
      相关资源
      最近更新 更多