2011-08-24 13 views
5

Vorrei tradurre la mia applicazione ExtJS in diverse lingue. Il mio problema è che sto usando il framework ExtC MVC e la maggior parte dei miei file JS sono scaricati dinamicamente dal framework stesso.ExtJS MVC, caricamento dinamico e i18n

La soluzione ideale (che ho pensato) sarebbe avere un'opzione aggiuntiva nell'Ext.Loader (o nel mio Ext.app.Application) che definirebbe la lingua da utilizzare e, a seconda di ciò, per scaricare automaticamente tale file come "a.MyClass.fr.js" dopo aver caricato il mio "a.MyClass.js" (che conterrebbe un Ext.apply, sovrascrivendo le mie risorse stringa). Questo probabilmente non è disponibile nel framework ExtJS al momento.

La soluzione alternativa che riesco a vedere è eseguire un trucco sul lato server. Innanzitutto, un cookie verrebbe creato sul client, per impostare la lingua. Sul lato server, potrei catturare tutte le richieste ai file JS, quindi se un cookie è impostato (= 'fr' per esempio), combinerei il file JS richiesto (MyClass.js) con l'amico di i18n (MyClass .fr.js) dinamicamente sul server e restituisce il risultato. Funzionerebbe, ma è davvero complicato perché implica altre cose (il caching ...).

Forse il modo migliore è quello di realizzare il primo comportamento che ho descritto nel quadro ExtJS me stesso ...

Cosa ne pensi? Sto cercando un modo davvero pulito e pulito di farlo! Grazie :)

risposta

9

Recentemente ho faticato con lo stesso problema.

Trovare un modo pulito per fare questo è stata una vera sfida - la maggior parte delle alternative erano o ..

1) duplicare i vostri base di codice per ogni locale (WTH)

2) Scaricare file localizzati imperativi ciascuna della vostra componenti (manutenzione inferno? Che dire dei poveri traduttori?)

3) Utilizzare/generare un file statico contenente traduzioni e fare riferimento ad esso (tutte le lingue vengono scaricate? Passo aggiuntivo per generarlo? Come tenerle sincronizzate? ?)

ho cercato di ottenere il migliore dei mondi possibili e si è conclusa con una classe di utilità responsabile:

1) Caricare i file di traduzione ExtJS (che si applicano essenzialmente sostituzioni per i componenti ExtJS base)

2) Caricamento di un resourcebundle delle proprietà specifiche della locale (specificando le impostazioni locali da caricare) dal server.

3) Prototipazione stringa con un metodo translate() che interroga l'archivio caricato (contenente il pacchetto di messaggi dal server) e restituisce la traduzione in base al valore della stringa.

Questo è il senso delle cose:

Bundle & prototipazione:

localeStore.load({ 
    callback : function(records, operation, success) { 
     // Define translation function (NB! Must be defined before any components which want to use it.) 
     function translate() { 
      var record = localeStore.getById(this.valueOf()) ; 
      if(record === null) { 
       alert('Missing translation for: ' + this.valueOf()); // Key is not found in the corresponding messages_<locale>.properties file. 
       return this.valueOf(); // Return key name as placeholder 
      } else { 
       var value = record.get('value'); 
      } 
      return value; 
     } 

     String.prototype.translate = translate; 
     callback.call(); // call back to caller(app.js/Ext.Application), loading rest of application 
    } 
}); 

Come esempio da una vista:

this.copyButton = Ext.create('Ext.button.Button', { 
    disabled: true, 
    text: 'DOCUMENT_LIBRARY_MENU_COPYTO_BUTTON'.translate(), 
    action: 'openCopyDialog' 
}); 

Bundle sul server (mesages_en.properties): DOCUMENT_LIBRARY_MENU_COPYTO_BUTTON = Copia file e tc ..

Pro:

codice
  • senza fronzoli, 'Your_key'.translate() lo rende facile da leggere e consapevoli che questo è una stringa localizzata
  • Nessuno/poco overhead di manutenzione (Keeping un file override per ogni locale? Gesù ..)
  • Carica solo il locale di cui hai bisogno, non l'intero shabang.
  • Se lo si desidera, è possibile anche avere la propria traduzione per i file internazionali ExtJS nello stesso pacchetto.
  • Si potrebbe scrivere unit test per assicurare che tutti i bundle contengono gli stessi tasti, evitando così traduzioni orfani in seguito

Contro:

  • sincrono - il negozio deve essere caricato prima i tuoi principale inizia app. Ho risolto questo problema aggiungendo un callback dalla classe di utilità che è stata chiamata una volta caricati tutti i testi.
  • No popolazione in tempo reale dei testi .. anche se non ho voglia di fare i miei utenti sovraccaricare il server sia: P

Finora il mio approccio ha funzionato abbastanza bene per le mie esigenze. Il carico del sito non è notevolmente più lento ei pacchetti (contenenti ~ 200 chiavi/valori per fascio) misurano a ~ 10kb durante il caricamento.

+0

Grazie a JaySee, un buon approccio a questo prototipo, rende il codice un piacere da leggere e fornisce ancora un approccio di traduzione semplice! – Paul

+0

Grazie per la soluzione elegante. Se usi [Ext.ux.Cache] (https://market.sencha.com/extensions/ext-ux-cache) che Cons può essere cambiato in Pro – Pencroff

0

Si dovrebbe prima completare la fase di sviluppo e costruire il vostro progetto o utilizzare il file ext-all.js per I18s di tradurre l'interfaccia utente

+0

Voglio che il mio i18n sia gestito correttamente dal sistema, durante la frase di sviluppo e dopo. Diverse persone lavorano sulle diverse classi e ognuna di esse conterrà i propri file di traduzione. Deve essere facile da aggiornare anche. Tutte le soluzioni attuali trovate non si adattano a questo scenario. – TigrouMeow

0

vedi: http://docs.sencha.com/ext-js/4-0/#!/example/locale/multi-lang.html lo script appropriato modificatore di lingua (/ ext/local/ext-lang-xxx.js) deve essere caricato dopo aver caricato ext (incluse le classi caricate dinamicamente). Nell'esempio sopra, probabilmente avrei usato Ext.Loader.loadScriptFile ma hanno valutato direttamente uno scaricato. L'unica altra cosa è che le classi devono essere costruite in lingue diverse o semplicemente si usano le variabili e si fa riferimento al file delle variabili specifico per lang.

si potrebbe anche usare una variabile nei percorsi usate:

var lang='fr'; 
Loader 
{ 
paths: 
{ 
    'Ext': '.', 
    'My': './src/my_own_folder'+'/'+lang 
} 
+0

Ma questo significa che ho bisogno di un grosso file caricato alla fine con tutte le traduzioni, no? Mi piacerebbe avere file locali per ciascuna delle mie classi (vediamo, ogni vista o ogni controller). In realtà ho sviluppato qualcosa e funziona, dovrei forse caricarlo su github? – TigrouMeow

2

non esiste attualmente alcuna soluzione così ho deciso di creare il mio mod/addon sul Ext.Loader. Ho caricato il codice su GitHub: https://github.com/TigrouMeow/extjs-locale-loader. È esattamente ciò di cui avevo bisogno e spero davvero che aiuti anche gli altri!

+0

è possibile avere una combinazione con più lingue e quando l'utente cambia il valore combo, tutte le applicazioni caricano le risorse locali per aggiornare la lingua ??? grazie –