我和韦斯顿有同样的问题,经过一些研究,我实现了一个解决方案,可以动态加载用户指定的语言。这对于 OP 来说可能为时已晚,但我将其放在这里以供其他可能对此过程有疑问的人将来参考。
我的解决方案可能不是处理此问题的理想方法,但它似乎与我的网站很好地配合。
我正在使用 Ember-cli 并包含 ember-i18n,用于国际化,以及 CLDR 来处理复数。我的站点使用 cookie 来存储用户语言,用于在站点加载时加载相应的语言文件。cookie 也被传递给 REST 服务(一些 API 调用返回可能包含翻译文本的对象)。我正在使用 jQuery-cookie 来处理我的 cookie。
首先,我创建了我的翻译文件,每种语言一个,这些只是我将使用 $.getScript 加载的 javascript 文件。我将它们存储在 Ember-cli 创建的 public/javascript 文件夹中的“翻译”文件夹中。
翻译-en.js
Ember.I18n.translations = {
'hello' : 'Hello World!',
...
}
翻译-fr.js
Ember.I18n.translations = {
'hello' : 'Bonjour Monde!',
...
}
然后我为 CLDR 设置初始化程序,它根据我的站点使用的用户语言 cookie 设置默认语言 - 如果 cookie 尚不存在,它默认为“en”并创建 cookie。
\app\initializers\cldr.js
export default {
name: 'cldr',
initialize: function() {
var lang = $.cookie('user-lang');
if (lang === undefined) { // no cookie exists yet
lang = 'en';
$.cookie('user-lang', lang, {expires:365, path:'/'});
}
CLDR.defaultLanguage = lang;
}
};
现在在 Application Route 的 beforeModel 函数中,我根据存储在 CLDR.defaultLanguage 中的值获取翻译文件。
\app\routes\application.js
export default Ember.Route.extend({
beforeModel: function() {
$.getScript('./javascript/translations/translations-' + CLDR.defaultLanguage + '.js')
.fail(function(jqxhr, reason, exception) {
// handle failure
});
}
});
如果您的网站有大量翻译字符串或多种语言,您可能不希望每次有人加载您的应用程序时都包含您的翻译文件,或者加载可能需要一段时间。在这种情况下,您可以使用 ajax 调用替换此 getScript 并让您的后端提供该文件。在我的情况下,没有太多的翻译字符串,所以这没关系。
现在,每当用户想要更改语言时,我所要做的就是更新我的 user-lang cookie 的值,然后重新加载站点,这将再次通过初始化程序和 beforeModel 函数并加载适当的语言文件。
export default Ember.Controller.extend({
actions: {
changeLanguage: function(lang) {
$.cookie('user-lang', lang);
window.location.reload();
}
}
});
每当用户重新加载页面或返回站点时,他们最后选择的语言将默认从 cookie 加载。当然,用户可以删除他们的 cookie 或从其他浏览器登录,在这种情况下,网站将返回默认的“en”语言。为了解决这个问题,用户的语言选择需要保留在后端的某个地方并在应用程序加载时获取 - 但这是另一项任务。