Angular 6 - i18n与ngx-translate的比较

35
我正在使用Angular 6开发一个大型项目。这个项目需要进行重要的i18n集成。我正试图做出正确的决定,以确定如何继续。
我认为可以选择以下两种方式之一: 1. ngx-translate (https://github.com/ngx-translate/core) 2. Angular i18n (https://angular.io/guide/i18n)
我倾向于选择第二种,即Angular的i18n。因为它是Angular自己内置的软件包,这让我感到更放心。显然,这对SEO更好,没有任何额外的工作,性能也略有提高。此外,现在已经发布了它,我认为ngx-translate可能会被弃用。 请参阅此处的大量信息:Angular 5 internationalization
但是,我仍有所保留:
  • 显然,Angular的版本相当新/仍在追赶(https://github.com/ngx-translate/core/issues/495)。它是否太新了?
  • 显然,我必须为每种语言单独构建一个网站(https://angular.io/guide/i18n#template-translations)??? 我真的不认为那是一件好事。对吗?还是说模板文件每次都是动态插入的?我知道使用ngx-translate,翻译后的文字只存储在.json文件中-我喜欢这种整洁的方式。我不认为我们想要许多不同的网站构建。

是否有一种方法可以使用angular i18n进行实时语言切换?即在页面上切换语言而无需重新加载/重新获取服务器数据?这就是他们所谓的JIT吗?

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

4个回答

22

这是基于个人观点的问题,因此不属于主题范围。

你需要一个单独的应用程序(即index.html + bundles)。但是你可以从单个URL中提供所有这些应用程序,决定在服务器上提供哪一个。希望随着Angular 7的推出,新的基于Ivy构建的动态i18n将可用,这种情况会发生变化。

不确定您的意思。针对您构建的语言环境的翻译是由Angular AOT编译器在编译时存储在生成的模板类中的。

不,即使在下一个版本的i18n中也不可能实现。同一个唯一的应用程序将能够以多种语言运行,但仍然必须在启动时选择语言,并且必须重新启动应用程序才能选择另一种语言。

没有。至少不是有效的方法。

那是他们所说的JIT吗?

不。JIT编译器是在浏览器启动时将您的HTML模板编译为JavaScript的工具。在生产环境中,您需要使用AOT编译器(也用于将翻译集成到生成的JS类中),该编译器会对模板进行类似的编译,但是是在构建时而不是运行时进行的。


1
希望随着 Angular 7 的推出,这将会有所改变。新的动态 i18n 建立在 Ivy 之上,将会提供更好的支持。2019 年是否有相关消息? - Emeric
2
很遗憾,@Curse目前还没有。Ivy将在Angular 8的预览版中推出,但i18n更改仍然不会出现。我现在的希望是它能在8中出现,或者在9中出现。 - JB Nizet
1
嗯,自从2020年以来,我可以告诉你,即使有ivy和angular 10,i18n仍然是一样的。 - Ernesto Alfonso

9
讨论仍在进行中,您可以在这里找到一些答案和意见,甚至直接来自Angular开发人员:https://github.com/ngx-translate/core/issues/495 个人而言,我会使用官方的i18n结构化应用程序,并最终使用ngx-translate库在代码中添加一些专门的翻译。
“是否有一种方法可以使用angular i18n进行实时语言切换?”实际上是可以的。 您需要构建不同的app dist,但是在完全部署后,您可以进行实时切换: 官方Angluar文档建议的教程

4
理解为什么开发人员喜欢像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”注册两个不同的键可以解决这个问题,在英语中它们恰好映射到相同的事物,但这要求您作为开发人员知道您的应用程序支持的所有语言,而在开发过程中或者您将不得不经历另一个迭代(时间就是金钱!)来获取客户反馈,然后添加单独的密钥,而如果为您的消息(文本)提供描述和含义,则翻译者将为您处理它,而您不需要了解其他语言(如果您知道西班牙语,请考虑这可能涉及虚拟语气和陈述语气动词形式在英语中相同但不是西班牙语)。
回答您的另一个问题“是否有一种方法可以使用angular i18n进行实时语言切换?”:是的。请查看关于应用程序状态管理的这篇精彩文章。长话短说,您需要在URL中反映客户端和持久状态。然后,您所需要做的就是在路径中添加区域设置前缀,这会导致您的Web服务器为您提供正确的区域设置构建。然后,无论您改变语言环境发生之前应用程序状态如何,都可以从URL中恢复(因为它“反映了持久和客户端状态”)。

1
Angular I18N 的一个巨大优势是对模板的影响最小化。您只需要在要本地化的每个元素上添加 i18n 属性即可。因此,
<p>Hello World<p>

变成

<p i18n>Hello World<p>

不需要大量更改标记,也不需要手动维护资源文件。如果你使用Angular或React的其他I18N库,你需要大量修改标记,例如

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

你需要手动将字符串添加到中性资源文件中,例如

"Hello World": "Hello World"

如果您想更改字符串,还必须记得更新资源文件中的键和值。

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

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


4
ngx-translate 中,你只需要写 <p translate>Hello World</p>,所以你的说法并不支持国际化。 - andreas
4
安德烈,你说得对。添加“translate”属性就足够了。但是你仍然需要手动将该字符串添加到资源文件中并进行维护。 - Jaska

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接