动态获取.js文件而不是导入它们

时间:2016-07-07 07:17:05

标签: reactjs xmlhttprequest react-intl

我有一个小应用程序,支持30多种语言。我使用react-intl来完成我的任务。在react-intl我必须导入每个本地文件大约7-8kbs的每个语言环境,而我想减少这些不必要的导入并且只想导入一个文件

app.js

import {IntlProvider, addLocaleData} from 'react-intl'
import ca from 'react-intl/locale-data/ca'
import cs from 'react-intl/locale-data/cs'
...
import hu from 'react-intl/locale-data/hu'
import id from 'react-intl/locale-data/id'
import enMessages from '../assets/translations/en.json'

Translations.getLocale('fr').then(function(localeData){
  addLocaleData(localeData);
  console.log("localeData");
  console.log(localeData);  //Code instead of array of objects
 }, function(status) {
  alert('Something went wrong.');
});

现在,cacshu等包含array of objectsjs文件中的Translations.js

我尝试使用XHR,但我没有返回对象数组,而是获得了.js文件中编写的代码。有没有办法可以动态导入js文件,或者我可以从XMLHttpRequest返回的代码中获取对象数组。

getLocale: function(lang, successHandler, errorHandler){ var url = 'http://localhost/img/' + lang + '.js'; return new Promise(function(resolve, reject) { var xhr = new XMLHttpRequest(); xhr.open('get', url, true); //xhr.responseType = 'application/javascript'; xhr.onload = function() { var status = xhr.status; if (status == 200) { resolve(xhr.response); } else { reject(status); } }; xhr.send(); }); //return message; }

<div class="element-group">
    <label class="element-label with-right-addon">Collection Date</label>
    <div class="element-input-wrap">
        <div class="input-group use-dpicker" data-date="">
            <input class="element-input date-input listen-change" id="drpNewCollectionDateSvc" type="text" > 
            <span class="input-group-addon"><i class="fa fa-calendar" onclick="$('#drpNewCollectionDateSvc').focus()" style="cursor:pointer"></i></span>                        
        </div>
    </div>
</div>

2 个答案:

答案 0 :(得分:0)

如果我理解正确,您将检索要从中检索输出的javascript代码。

一种解决方案是使用eval,尽管这通常不被认为是非常安全的。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval

您还可以使代码成为自动执行的函数,将输出放在全局变量上,然后从那里访问它。将js文件的内容作为脚本附加到head标记中,并使文件包含类似的内容。

myGlobalVar = (function() {
    return {
        key: val
    };
})();

我不知道您的translate.js文件的格式,但如果它是每种语言的固定输出,您也可以考虑将翻译放在json文件中。我认为这是最安全的解决方案。

答案 1 :(得分:0)

我设法动态加载语言环境文件,如下所示:

请注意,我的区域设置字符串格式可能不太理想,如果您不打算支持旧浏览器,请忽略polyfill。

import {addLocaleData}  from 'react-intl';

const locale = // get this from browser language

// ensure that the polyfill is loaded before calling this
const isUsingIntlPolyfill = Object.prototype.hasOwnProperty.call(window, 'IntlPolyfill');

// eg: turns 'fr-fr' into 'fr-FR' because intl polyfill locale files are formatted like this
const formatLocale = str => `${str.split('-')[0]}${str.split('-')[1] ? `-${str.split('-')[1].toUpperCase()}` : ''}`;

if (isUsingIntlPolyfill) {
    const polyfill = document.createElement('script');
    // path of the file might differ for your setup
    polyfill.setAttribute('src', `/i18n/polyfill/${formatLocale(locale)}.js`);
    document.getElementsByTagName('head')[0].appendChild(polyfill);
}

const script = document.createElement('script');
// path of the file might differ for your setup
script.setAttribute('src', `/i18n/${locale.split('-')[0]}.js`);
script.onload = () => {
    addLocaleData([...window.ReactIntlLocaleData[locale.substring(0, 2)]]);
    // your locale is loaded, do some more stuff from here ...
};
document.getElementsByTagName('head')[0].appendChild(script);