Load Locale File Dynamically using Requirejs

孤人 提交于 2019-12-01 18:59:24

You should be able to check user settings, construct a dependency string, pass it to Translator and then use it instead of localeData — r.js will ignore the dynamic dependency but should bundle EN locale.

if ( userLocale && userLocale !== 'en_US' ) {

    var localePath = 'json!locales/' + userLocale + '.json';
    require([ localePath ], function( locale ) {
        var translator = new Translator( locale );
    });

}

and inside Translator: "locale_data": passedData || englishData.

(or do the same inside the Translator module, like if ( userLocale !== 'en_US' ) { require([path], function(locale) {...}))

In theory it should work, though you cannot use simplified CommonJS here and should use callback-require, otherwise you'll get Module name ... has not been loaded yet for context error.

This is the solution I ended up doing. It worked out quite nicely, and I also learnt about using $.Deferred which was great!

The key for me was using the require text plugin as a loader in the code.

The default locale is set as a dependency, that way it's baked in the build as well.

Explanations are in the code below:

//in translator.js
define(function (require) {
    "use strict";

    var $ = require("jquery");
    var _ = require("underscore");
    var Jed = require("jed");
    var text = require("text");
    var defaultDictionary = require("json!locales/en_US.json");

    var Translator;

    Translator = (function () {
        var DEFAULT_LOCALE = "en_US";
        var defaultLocaleData = {
            locale: DEFAULT_LOCALE,
            dictionary: defaultDictionary
        };

        var createTranslator = function (localeData) {
            //create the actual Jed instance with the relevant dictionary
            var i18n = new Jed({
                "domain": "messages",
                "locale_data": localeData.dictionary
            });
            return i18n;
        };
        var parseLocaleDictionary = function (locale, dictionary) {
            //parse the dictionary JSON string loaded by text plugin...
            //handle errors in parsing if needed
        };
        //get to work here
        var getTranslatorForLocale = function (locale) {
            //$gettingData promise will be resolved when data for Jed is loaded and ready
            var $gettingData = $.Deferred();
            //$creatingTranslator promise will be returned to caller and will be resolved when everything's done
            var $creatingTranslator = $.Deferred();

            if (!locale || locale === DEFAULT_LOCALE) {
                //default locale, so resolve right away because we required it already
                $gettingData.resolve(defaultLocaleData);
            }
            else {
                //need to load the dictionary from here
                var dictionaryUrl = require.toUrl("locales/" + locale + ".json");
                //this is the dynamic loading
                text.get(
                    dictionaryUrl,
                    function (dictionary) {
                        //if successful, parse the JSON string and use that dictionary
                        var localeData = parseLocaleDictionary(locale, dictionary);
                        $gettingData.resolve(localeData);
                    },
                    function (error) {
                        //on load error, use the default and resolve promise
                        $gettingData.resolve(defaultLocaleData);
                    });
            }

            //once the data is ready, we can create the translator instance
            $gettingData.done(function (localeData) {
                var i18n = createTranslator(localeData);
                //notify caller that translator is ready
                $creatingTranslator.resolve(i18n);
            });

            return $creatingTranslator.promise();
        };

        return {
            //this function is returned to the user of Translator
            getTranslator: function (locale) {
                var $gettingTranslator = getTranslatorForLocale(locale);
                return $gettingTranslator;
            }
        };
    }());

    return Translator;
});
//in app.js
define(function (require) {
    var Translator = require("translator");
    //in app.js
    var myTranslator;
    var userLocale = "fr_FR";
    //this is a promise that will be resolved when translator is ready
    var $getTranslator = Translator.getTranslator(userLocale);
    //when translator is ready, store it
    $getTranslator.done(function (translator) {
        myTranslator = translator;
    });
    //...
});
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!