简体   繁体   English

动态设置RequireJS i18n语言环境

[英]Setting RequireJS i18n locale dynamically

I am using the RequireJS i18n plugin to load translations into my application. 我正在使用RequireJS i18n插件将翻译加载到我的应用程序中。 I'm struggling with the concept of runtime determination of a user's preferred language . 我正在努力解决用户首选语言运行时确定问题

The plugin works well if you're using navigator.language to determine the user's preferred language, but in my app, the user's language is held in a database on the server. 如果您使用navigator.language来确定用户的首选语言,该插件可以很好地工作,但在我的应用程序中,用户的语言保存在服务器上的数据库中。 So I need to set the locale at runtime: 所以我需要在运行时设置语言环境:

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

So what I need is a clever way of setting userLocale before RequireJS has loaded my application. 所以我需要的是 RequireJS加载我的应用程序之前设置userLocale一种聪明的方法。 Does anyone know what would be the best way to achieve this? 有谁知道最好的方法是什么? Possibilities include: 可能性包括:

1) Setting userLocale outside of my application, in a non-AMD way: 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']);

This makes me a little bit sad as it means some of my application will be outside of RequireJS, and thus untidy. 这让我有点难过,因为这意味着我的一些应用程序将在RequireJS之外,因此不整洁。 It also means all the user's localization settings (language timezone, date format, numeric format) will be held in the global namespace. 它还意味着所有用户的本地化设置(语言时区,日期格式,数字格式)将保存在全局命名空间中。

2) Having a separate require call to retrieve localization settings 2)单独的require调用以检索本地化设置

I'm not sure how this work, but perhaps: 我不确定这是如何工作的,但也许:

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

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

require(['app']);

Perhaps this wouldn't work due to asynchronousness? 也许由于异步性,这不起作用? Also the app would not have access to the Localization object, so it would still need to be stored as a global variable. 此外, app无法访问Localization对象,因此仍需要将其存储为全局变量。

Can anyone see a good solution to this problem? 有谁能看到这个问题的一个很好的解决方案? Has anyone used the RequireJS i18n plugin to do something similar? 有没有人使用RequireJS i18n插件做类似的事情?

It seems after a lot of research, the best approach for solving this problem is to check localStorage for a locale value. 经过大量研究后,解决此问题的最佳方法是检查localStoragelocale值。 If this hasn't been set yet, I load the application using a dummy language: 如果尚未设置,我使用虚拟语言加载应用程序:

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

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

require(['app']);

I use a language called dummy , set to an empty object in my nls file. 我使用一种名为dummy的语言,设置为我的nls文件中的空对象。 Using a dummy, rather than a default, means I don't have to guess what the user's language might be, and potentially force them to download a whole load of translations in the wrong language: 使用虚拟而不是默认意味着我不必猜测用户的语言可能是什么,并可能强迫他们以错误的语言下载大量翻译:

define({
    "root": false,
    "dummy": {}, //dummy language with no translations if user language is unknown
    "fr": true,
    "en": true,
    "en-uk": true,
    "fr-fr": true
});

Then, when the app has loaded and the user has been logged in, I query the database using a service call, set the language in localStorage and reload the app using location.reload() : 然后,当应用程序加载并且用户已登录时,我使用服务调用查询数据库,在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();
    }

Of course, I need to support old version of IE so I have also included fallbacks using userData , but this is the gist of the solution. 当然,我需要支持旧版本的IE,所以我还使用userData包含了回退,但这是解决方案的要点。

This approach is partially taken from how the guys at RESThub do it. 这种方法部分取决于RESThub的人员如何做到这一点。

Another option, if your page is dynamically generated with a template system, is to have the require.config({config {..} }) inlined into the generated HTML... say like this: 如果您的页面是使用模板系统动态生成的,另一个选项是将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(..) can be called multiple times, but should be done before your app is loaded. require.config(..)可以多次调用,但应该在加载应用程序之前完成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM