RactiveJS国际化的良好实践(使用RequireJS)



我已经构建了一个基于RactiveJS的web应用程序。它使用RequireJS来处理模块和依赖关系。Racive模板是用rv加载的。

现在我想支持多种语言(最初只有德语和英语)。

所以我的问题是:

在RactiveJS中实现国际化的良好实践是什么

到目前为止,我看到了两种选择:

1.从模板中剥离所有文本,将它们放在资源文件中,并通过查找方法传递
缺点:
<div>The Item {{name}} is used <b>{{count}}</b> times.</div> 等情况下,要么将文本分开,留下无意义的块,要么中断数据绑定

2.重复模板
缺点:
•重复的模板代码
•无法弄清楚如何使用RequireJS Optimizer 为模板构建单独的语言包

3
还有其他想法吗?

BTW:可以在语言更改时重新加载整个应用程序。我更喜欢一个解决方案,其中只有当前所选语言的资源将通过RequireJS加载。

没有规范的方法可以做到这一点。然而,您可以通过使用decorator来摆脱它。将文本包装在<span>中,并向<span>添加一个装饰器。decorator所做的是获取<span>的内容,从准备好的映射中获取翻译,并替换该文本。

<div>
  <span decorator="i18n">Some random text to translate</span>
</div>

要生成翻译文件,您可以使用grunt/gulp/whatthing工具任务来运行所有组件文件,解析其中的HTML部分,并使用decorator="i18n"查找元素。然后根据它生成JSON模板,并手动填写翻译。

{
  "Some random text to translate": "Alcuni testo casuale da tradurre",
  ...
}

然后,您可以有某种类型的全局指示符来向decorator模块发出要加载哪些翻译映射的信号。由于翻译可以随时更改,因此无法通过RequireJS静态加载。映射将需要AJAX关闭或通过动态require调用完成。无论哪种方式,优化器都不会包括翻译。

此外,渲染过程中还有一些开销,因为使用该装饰器渲染的每个组件都会动态更改文本。

要解决1+2的问题,即在不复制所有模板的同时保持模板的意义,请考虑将主要语言(比如英语)的文本作为默认提供给翻译函数。

根据这个Racive问题中的讨论,并由kurdin在这个小提琴中演示,你的模板可能看起来是这样的:

<p>{{{ t('Hello <strong>{{name}}</strong> and have a nice day!', 'hello', {name: user.name}) }}}</p>

然后,定义一个专门处理默认值的转换函数t

Translations = []   // load those however you want
Translations["ru"] = {
       localization: 'пример локализации',
       hello: "Привет <strong>{{name}}</strong> хорошего тебе дня!",
       language: 'Язык: {{lang}} ',
       lang: 'Русский'
}
I18n.translations = Translations;
I18n.defaultLocale = "en";
function t(defaultText, name, context) {
    return (I18n.locale === I18n.defaultLocale) ? defaultText : I18n.t(name, context);
}

缺点是:

  1. 不一致。默认语言在模板中是硬编码的,即默认语言与语言包的位置不同
  2. 开销:您可能会加载两种语言的数据,因为默认值总是加载在模板中

为了解决第一个问题,即一致性,您可能也想提供一个英语语言包,并跳过自定义t函数。

最新更新