动态设置RequireJS i18n区域设置

7
我正在使用RequireJS i18n插件将翻译加载到我的应用程序中。我在理解运行时确定用户首选语言的概念方面遇到了困难。
如果您使用navigator.language来确定用户的首选语言,则该插件可以很好地工作,但是在我的应用程序中,用户的语言保存在服务器上的数据库中。因此,我需要在运行时设置区域设置:
require.config({
    config: {
        i18n: {
            locale: userLocale
        }
    }
});

我需要一个聪明的方法,在RequireJS加载我的应用程序之前设置userLocale。有人知道最好的方法是什么吗?可能的方式包括:

1) 在我的应用程序外部以非AMD方式设置userLocale

//run Ajax call to determine user's localization preferencess
var Localization = Localization || getUserLocalization(); 

//and then...
require.config({
    config: {
        i18n: {
            locale: Localization.userLocale
        }
    }
});

require(['app']);

这让我有些难过,因为这意味着我的一些应用程序将超出RequireJS的范畴,因此不够整洁。这也意味着所有用户的本地化设置(语言时区、日期格式、数值格式)将保存在全局命名空间中。
2) 单独使用require调用以检索本地化设置
我不确定这是怎么工作的,但也许是这样的:
var Localization = require(['localization']);

require.config({
    config: {
        i18n: {
            locale: Localization.userLocale
        }
    }
});

require(['app']);

也许这不会起作用,因为它是异步的?而且app将无法访问Localization对象,因此仍然需要将其存储为全局变量。
有人能看到解决这个问题的好方法吗?有人使用RequireJS i18n插件来做类似的事情吗?
2个回答

5

经过大量研究,解决此问题的最佳方法似乎是检查localStorage中是否有locale值。如果尚未设置此项,则使用虚拟语言加载应用程序:

var locale = localStorage.getItem('locale') || 'dummy';

require.config({
    config: {
        i18n: {
            locale: locale
        }
    }
});

require(['app']);

我使用一种称为“dummy”的语言,在我的nls文件中设置为空对象。使用虚拟语言而不是默认语言意味着我不必猜测用户的语言可能是什么,并且潜在地迫使他们下载错误语言的大量翻译。
define({
    "root": false,
    "dummy": {}, //dummy language with no translations if user language is unknown
    "fr": true,
    "en": true,
    "en-uk": true,
    "fr-fr": true
});

然后,当应用程序加载并且用户已登录时,我使用服务调用查询数据库,将语言设置为 localStorage 并使用 location.reload() 重新加载应用程序:

    //retrieve user object (including preferred locale) from service call
    user = getUserObject(userId); 

    locale = localStorage.getItem('locale');

    if (!locale || locale !== user.locale) {

        localStorage.setItem('locale', user.locale);

        //reload the app
        location.reload();
    }

当然,我需要支持旧版本的IE,因此我还使用了userData来提供后备方案,但这就是解决方案的要点。
这种方法部分地来自RESThub的做法。

1
如果您的页面是通过模板系统动态生成的,另一种选择是将require.config({config {..} })内联到生成的HTML中...就像这样:
<!-- load require.js -->
<script src="js/lib/require.js"></script>
<!-- standard config options in this file -->
<script src="js/config.js"></script>
<!-- user specific config inlined in the Dynamic HTML -->
<script>
  // now set the user's preferred locale
  require.config({
    config : { 
      i18n: {
        locale: '<% user.locale %>' // i.e. use PHP to insert user's preferred language
      }
    }
  });
  require(['app']); // Call your main app here
</script>

require.config(..) 可以被多次调用,但应在加载应用程序之前完成。


谢谢Troy。在我的使用情况中,所有与数据层的交互都是通过对RESTful API的AJAX调用完成的,但这可能会帮助那些HTML是在服务器上生成的人。 - Simon Adcock

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