Angular 6 - i18n 与 ngx-translate

Angular 6 - i18n vs. ngx-translate

我正在使用 angular 6 处理一个大型项目。该项目需要重要的 i18n 集成。我正在尝试就如何进行做出正确的决定。

我的看法是我可以选择:

  1. ngx-翻译 (https://github.com/ngx-translate/core)
  2. Angular i18n (https://angular.io/guide/i18n)

我倾向于选择选项2; Angular 的国际化。这是因为它是 Angular 自己的内置包,而且更适合我。显然,它对 SEO 也更好,并且在没有任何解决方法的情况下性能略好。此外,现在它已发布,我认为 ngx-translate 可能已被弃用。 这里有很多信息:.

但是我的保留意见是:

有没有办法用 angular i18n 进行实时语言切换?即在页面上切换语言而不从服务器重新加载/重新获取数据?这就是他们所说的 JIT 吗?

有没有人试过https://github.com/robisim74/angular-l10n?看起来也很不错。

Is it too new to take on?

这是基于观点的,因此是题外话

Apparently I have to have a separate website

您需要一个单独的应用程序(即 index.html + 捆绑包)。但是您可以从一个 URL 中为所有这些应用程序提供服务,并决定在服务器上提供哪个应用程序。当基于 Ivy 构建的新动态 i18n 可用时,Angular 7 会(希望)改变这种情况。

is it a case that template files are dynamically inserted each time?

不确定你的意思。您构建的区域设置的翻译在编译时由 Angular AOT 编译器存储在生成的模板 类 中。

Is there a way to do live language switching with angular i18n?

不,下一版本的 i18n 也不可能做到这一点。相同的、独特的应用程序将能够 运行 多种语言,但仍然需要在启动时选择语言,并且您必须重新启动应用程序才能选择另一种语言。

Is there a way to do live language switching with angular i18n?

没有。至少效率不高。

Is that what they call JIT?

没有。 JIT 编译器在浏览器启动时将 HTML 模板编译成 JavaScript。在生产中,您使用 AOT 编译器(它也用于将翻译集成到生成的 JS 类),它对模板进行类似的编译,但在构建时而不是 运行 时。

讨论仍在继续,您可以在这里找到一些答案和意见,甚至直接来自 Angular 开发人员: https://github.com/ngx-translate/core/issues/495

就个人而言,我会使用官方 i18n 构建应用程序,并最终使用 ngx-translate 库在代码中添加一些专用翻译。

Is there a way to do live language switching with angular i18n?

其实是有的。您需要为您的应用程序构建不同的 dist,但您可以在完全部署后实时切换:

Official Angluar docs and suggested tutorial

开发人员喜欢 ngx-translate 之类的库来处理国际化是可以理解的。毕竟,通过将翻译问题变成 1v1 映射,我们的生活变得如此轻松。不幸的是,这不是它处理人类语言的方式。一个人有两个人知道不止一种语言可以更好地理解这种方法的缺点。

这是一个小例子: 假设您有一个差旅费用应用程序,您有一个表格视图,其中一列标题为 "times",指示报告费用的时间。然后想象在这样的应用程序中,你有一个迷你计算器来对你的费用进行基本验证,它恰好有一个乘法按钮 x 和一个停留说 "times"。当您执行 ngx-translate 时,您会使用相同的密钥 "TIMES" 将它们都提取出来,然后翻译人员会为您返回一个翻译。但是 "time" 的第一次出现不一定与所有其他语言中的第二个翻译相同。以西班牙语为例:

  • "two TIMES three"(和计算器一样)-> "dos POR tres"
  • "expense TIMES"(如表格视图)-> "TIEMPOS de gasto"

这实际上就是为什么国际化正朝着使用更复杂的格式(例如 XLF)的方向发展,以支持含义、描述(在 Angular 的情况下)而不是旧的 1 深度 JSON 风格,无法根据上下文进行翻译。

现在您可能会争辩说,这可以通过为 "times" 注册两个不同的密钥来解决,在英语中它们恰好映射到同一事物,但这需要您作为开发人员了解您的应用程序支持的所有语言在开发时,否则您将不得不经历另一次迭代(时间就是金钱!)来获取客户的反馈,然后添加一个单独的密钥,而如果您为您的消息(文本)提供描述和含义,那么翻译人员会为您处理,而无需你对另一种语言有任何了解(如果你懂西班牙语,想想这与英语中相同但不是西班牙语的虚拟语气和指示性动词形式有多复杂)。

回答你的另一个问题"Is there a way to do live language switching with angular i18n?":是的。查看 this awesome article 关于应用程序中的状态管理。长话短说,您需要在 URL 中反映您的客户端和持久状态。然后你需要做的就是在你的路径中添加一个语言环境前缀,这会导致你的网络服务器为你提供正确的语言环境构建。然后,无论您的应用程序在更改区域设置更改操作发生之前处于什么状态,都可以从 URL 中恢复(因为它 "reflects both the persistent and client state")。

Angular I18N 的一大优势是它对模板的影响很小。您只需在要本地化的每个元素上添加 i18n 属性。所以

<p>Hello World<p>

变成

<p i18n>Hello World<p>

无需大量更改标记,也无需手动维护资源文件。如果您将任何其他 I18N 库用于 Angular 或 React,则需要大量修改标记,例如

<p>Translate("Hello World")<p>

并且您必须手动将字符串添加到中性资源文件中,例如

"Hello World": "Hello World"

然后如果你想改变字符串你也必须记得更新资源文件中的键和值。

使用 Angular I18N,您可以使用提取工具来创建和维护中性资源文件。

AngularI18N 当前缺少的是在源代码中本地化字符串的能力。不过这个功能很快就会出现。