这个 polyfill 似乎是现在最好的方法:
https://github.com/ngx-translate/i18n-polyfill
它允许您将要翻译的任何内容包装在一个i18n()
函数中(此 API 可能会保留在 Angular 的未来版本中 - 请参阅我在此答案底部的注释)。
polyfill 主要由负责 i18n 的 Angular 团队成员 Olivier Combe 编写:
对于 Angular 5,安装时需要 0.2.0 版本:
npm install @ngx-translate/i18n-polyfill@0.2.0 --save
对于 Angular 6,获取最新版本 - 当前为 1.0.0:
npm install @ngx-translate/i18n-polyfill@1.0.0 --save
我得到了适用于 Angular 5的 JIT 和 AOT 编译的 polyfill(它也适用于 Angular 6)。以下是翻译成单一语言所需要做的事情(这是实现此功能的好方法 - 然后您可以稍后让多种语言工作,我将在下面进一步解释):
app.module.ts
将以下导入添加到根 Angular 模块:
import { TRANSLATIONS, TRANSLATIONS_FORMAT } from '@angular/core';
import { I18n } from '@ngx-translate/i18n-polyfill';
添加以下常量,并在根模块中指定提供程序:
// add this after import + export statements
// you need to specify the location for your translations file
// this is the translations file that will be used for translations in .ts files
const translations = require(`raw-loader!../locale/messages.fr.xlf`);
@NgModule({ ....
providers:
[
I18n,
{provide: TRANSLATIONS, useValue: translations},
{provide: TRANSLATIONS_FORMAT, useValue: 'xlf'},
...
关于使用 AOT 编译的注意事项:如果您使用 AOT 编译来翻译模板,.ts 文件中的消息的翻译仍将在运行时使用 JIT 编译完成(这就是为什么您需要引用TRANSLATIONS
而TRANSLATIONS_FORMAT
不是仅在您的构建脚本)。
*.ts
在要提供翻译的 .ts 文件中,添加以下内容:
import { I18n } from '@ngx-translate/i18n-polyfill';
constructor(private i18n: I18n) {
console.log(i18n("This is a test {{myVar}} !", {myVar: "^_^"}));
}
这表明您甚至可以在要翻译的消息中包含插值。
您可以像这样使用 i18n 定义(即使用指定翻译“源”ID、含义、描述):
this.i18n({value: 'Some message', id: 'Some message id', meaning: 'Meaning of some message', description: 'Description of some message'})
您仍然需要提取消息,并且可以使用 ngx-extractor 工具来执行此操作。这包括在安装 polyfill 时,我在下面添加了一个示例,说明它在 npm 脚本中的用法。另请参阅polyfill 页面上的自述文件。
多种语言
为了支持在多种语言之间切换,您需要一个工厂供应商来进行翻译。polyfill 页面的自述文件中有详细信息。你的根模块中需要这样的东西(或者对于 AOT 编译,将返回值替换为localeFactory
一个检测你的应用程序当前正在运行的 AOT 编译语言变体的函数):
export function localeFactory(): string {
return (window.clientInformation && window.clientInformation.language) || window.navigator.language;
}
providers:
[
{
provide: TRANSLATIONS,
useFactory: (locale) => {
locale = locale || 'en'; // default to english if no locale provided
return require(`raw-loader!../locale/messages.${locale}.xlf`);
},
deps: [LOCALE_ID]
},
{
provide: LOCALE_ID,
useFactory: localeFactory
},
消息提取和 xliffmerge
所有这些都与xliffmerge兼容,这是一个很好的工具,可以自动合并您添加的任何新翻译,而不会覆盖现有翻译。Xliffmerge 还可以使用 Google 翻译自动执行翻译(您需要 Google 翻译 API 密钥)。为此,在进行实际的 AOT 构建之前,我按以下顺序进行提取和合并/翻译:
"extract-i18n-template-messages": "ng xi18n --outputPath=src/locale --i18n-format=xlf",
"extract-i18n-ts-messages": "ngx-extractor --input=\"src/**/*.ts\" --format=xlf --out-file=src/locale/messages.xlf",
"generate-new-translations": "xliffmerge --profile xliffmerge.json en fr es de zh"
网站特定语言版本的 AOT 构建如下所示:
"build:fr": "ng build --aot --output-path=dist/fr --base-href /fr/ --i18nFile=src/locale/messages.fr.xlf --i18nFormat=xlf --locale=fr",
这个 polyfill 的当前状态:
这主要由负责 i18n 的 Angular 团队成员 Olivier Combe 编写。在这个阶段,这是一个“推测”的 polyfill,用于翻译 .ts 文件中的变量或字符串。它很可能会被 Angular 内置的 API 所取代,该 API 将非常相似,因此以后升级应该是可以合理管理的。这是来自 Github 页面的免责声明:
这个库是一个推测性的 polyfill,这意味着它应该替换未来的 API。如果 API 不同,将在可能和必要的情况下提供迁移工具。
关于在即将到来的 Angular 6 小版本中对代码中变量/字符串的翻译的支持进行了一些讨论。
这是 Olivier Combe 的引述(从今年 3 月开始),来自 Github 上的以下讨论:
https://github.com/angular/angular/issues/11405
运行时 i18n 的第一个 PR 已合并到 master 中,以及我们将用来测试功能的 hello world 演示应用程序。它在运行时工作,理论上支持代码翻译,即使还没有服务。目前它的支持非常少(静态字符串),我们正在努力添加新功能(我将在下周进行提取工作,然后是带有占位符和变量的动态字符串)。之后,我们将提供代码翻译服务。一旦新功能完成,它就会被合并到 master 中,您不必等待新的专业。