2016-07-07 9 views
0

Ich habe eine kleine App, die 30+ Sprachen unterstützt. Ich habe react-intl verwendet, um meine Aufgabe zu erfüllen. In react-intl bekam ich jedes Gebietsschema importieren, in dem jede lokale Datei herum 7-8kbs, während ich diese unnötigen Importe reduzieren wollen und nur eine DateiErhalte eine .js-Datei dynamisch, anstatt sie zu importieren

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.'); 
}); 

Nun ist die ca, importieren möchten cs , hu usw. enthalten array of objects zurückgegeben von den entsprechenden js Dateien.

Ich versuchte mit XHR, aber anstatt das Array von Objekten zurückzugeben, bekomme ich den Code, der in der .js-Datei geschrieben wird. Gibt es eine Möglichkeit, die js-Datei dynamisch zu importieren oder wenn ich das Array von Objekten aus dem von XMLHttpRequest zurückgegebenen Code abrufen kann.

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

Antwort

0

Wenn ich Sie richtig verstehe, rufen Sie den Javascript-Code, mit dem Sie die Ausgabe von abrufen möchten.

Eine Lösung ist Eval zu verwenden, obwohl dies im Allgemeinen nicht als sehr sicher gilt. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval

Sie können den Code auch zu einer automatisch ausgeführten Funktion machen, die die Ausgabe auf eine globale Variable setzt und von dort auf sie zugreift. Fügen Sie den Inhalt der js-Datei als Skript in das head-Tag ein und sorgen Sie dafür, dass die Datei so etwas enthält.

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

Ich weiß nicht, das Format Ihrer translate.js Dateien, aber man könnte auch prüfen, die Übersetzungen in einer JSON-Datei setzen, wenn es dich um einen festen Ausgang für jede Sprache ist. Was ich denke, wäre die sicherste Lösung.

0

ich es geschafft, die locale-Dateien dynamisch wie folgt zu laden:

Beachten Sie, dass meine locale String Formatierung nicht ideal sein könnte, und die polyfill ignorieren, wenn Sie auf die Unterstützung von alten Browsern nicht planen.

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); 
Verwandte Themen