0

我有一个支持 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,cshu包含array of objects从各自js文件返回的内容。

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

Translations.js

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;
}
4

2 回答 2

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);
于 2017-01-06T17:16:39.597 回答
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 文件中,如果它是每种语言的固定输出。我认为这将是最安全的解决方案。

于 2016-07-07T08:12:39.460 回答