我有一个小应用程序,支持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.');
});
现在,ca
,cs
,hu
等包含array of objects
个js
文件中的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>
答案 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);