动态设置RequireJS i18n语言环境

Sim*_*ock 7 javascript internationalization requirejs

我正在使用RequireJS i18n插件将翻译加载到我的应用程序中.我正在努力解决用户首选语言运行时确定问题.

如果您使用navigator.language确定用户的首选语言,该插件可以很好地工作,但在我的应用程序中,用户的语言保存在服务器上的数据库中.所以我需要在运行时设置语言环境:

require.config({
    config: {
        i18n: {
            locale: userLocale
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

所以我需要的是userLocale RequireJS加载我的应用程序之前设置一个聪明的方法.有谁知道最好的方法是什么?可能性包括:

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

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

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

require(['app']);
Run Code Online (Sandbox Code Playgroud)

这让我有点难过,因为这意味着我的一些应用程序将在RequireJS之外,因此不整洁.它还意味着所有用户的本地化设置(语言时区,日期格式,数字格式)将保存在全局命名空间中.

2)单独的require调用以检索本地化设置

我不确定这是如何工作的,但也许:

var Localization = require(['localization']);

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

require(['app']);
Run Code Online (Sandbox Code Playgroud)

也许由于异步性,这不起作用?此外,app无法访问该Localization对象,因此仍需要将其存储为全局变量.

有谁能看到这个问题的一个很好的解决方案?有没有人使用RequireJS i18n插件做类似的事情?

Sim*_*ock 5

经过大量研究后,解决这个问题的最佳方法是检查localStorage一个locale值.如果尚未设置,我使用虚拟语言加载应用程序:

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

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

require(['app']);
Run Code Online (Sandbox Code Playgroud)

我使用一种叫做的语言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
});
Run Code Online (Sandbox Code Playgroud)

然后,当应用程序加载并且用户已登录时,我使用服务调用查询数据库,设置语言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();
    }
Run Code Online (Sandbox Code Playgroud)

当然,我需要支持旧版本的IE,所以我还包括使用回退userData,但这是解决方案的要点.

这种方法部分取决于RESThub的人员如何做到这一点.