2011-08-24 46 views
5

我想用不同的語言翻譯我的ExtJS應用程序。我的問題是我使用ExtJS MVC框架,並且我的大部分JS文件都是由框架自己動態下載的。ExtJS MVC,dynamic loading and i18n

理想的解決方案(我想到的)將是在Ext.Loader(或在我的Ext.app.Application)中有一個額外的選項,它將定義要使用的語言,並根據此自動下載加載我的「a.MyClass.js」(這將包含一個Ext.apply,覆蓋我的字符串資源)之後的文件「a.MyClass.fr.js」。目前在ExtJS框架中可能無法使用。

我可以看到的替代解決方案是在服務器端執行一個技巧。首先,客戶端會創建一個cookie,以設置語言。在服務器端,我可以捕獲所有對JS文件的請求,然後如果設置了一個cookie(例如='fr'),我會將請求的JS文件(MyClass.js)與其i18n的朋友(MyClass .fr.js)在服務器上動態並返回結果。這是行得通的,但它非常棘手,因爲它意味着其他事情(緩存......)。

也許最好的辦法是落實我在ExtJS的框架描述自己的第一行爲......

你覺得呢?我正在尋找一種非常乾淨整潔的方式!謝謝:)

回答

9

我最近還面臨同樣的問題。

找到一個乾淨的方式做到這一點是相當大的挑戰 - 大多數替代要麼..

1)複製每個區域設置您的代碼庫(WTH)

2)下載本地化的文件重寫你的每一個組件(維護地獄?那些可憐的翻譯者呢?)

3)使用/生成一個包含翻譯並引用它的靜態文件(所有語言被下載?額外構建步驟來生成它?你如何保持它們同步?)

我試圖讓世界上最好的,並結束了與負責一個實用工具類:

1)加載ExtJS的翻譯文件(這基本上適用替代來ExtJS的基本組件)

2 )從服務器加載特定於語言環境的屬性resourcebundle(指定要加載的語言環境)。

3)使用translate()方法查詢加載的存儲(包含來自服務器的消息包)並返回基於字符串值的轉換的原型字符串。

這是事物的要旨:

捆綁&原型:

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

如從一個視圖的示例:

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

束上的服務器(mesages_en.properties ): DOCUMENT_LIBRARY_MENU_COPYTO_BUTTON =複製檔案 e TC ..

優點:

  • 沒有大驚小怪代碼,「Your_key'.translate()可以很容易地閱讀和了解,這是一個本地化的字符串
  • 無/低維護開銷(保持每個語言環境的重寫文件?耶穌..)
  • 你只加載你需要的語言環境 - 不是整個shabang。
  • 如果您真的想要,甚至可以在同一個包中爲ExtJS語言環境文件提供自己的翻譯。
  • 你可以編寫單元測試,以確保所有包包含相同的密鑰,從而避免孤立的翻譯後

缺點:

  • 同步 - 商店必須在主應用程序開始之前被加載。我通過從實用程序類中添加一個回調來解決此問題,一旦所有文本加載後都會調用該回調函數。
  • 沒有文字的..雖然我不想讓我的用戶的實時人口超負荷的服務器或者:P

到目前爲止,我的方法已經制定了相當不錯我的要求。 網站加載速度並不明顯較慢,並且在加載過程中捆綁包(每個包含約200個鍵/值)在〜10kb處測量出來。

+0

Thanx JaySee,不錯的方法,原型,使代碼高興閱讀,仍然提供了一個簡單的翻譯方法! – Paul

+0

感謝您的優雅解決方案。如果使用[Ext.ux.Cache](https://market.sencha.com/extensions/ext-ux-cache)Cons可以更改爲專業人員 – Pencroff

0

你應該先完成你的發展階段,建立自己的項目或使用EXT-all.js文件I18s翻譯你的UI

+0

我希望我的i18n能夠在開發期間和之後由系統正確管理。不同的人在不同的課上工作,他們每個人都會帶着他們的翻譯文件。它也必須容易更新。目前發現的所有解決方案都不適合這種情況。 – TigrouMeow

0

見:http://docs.sencha.com/ext-js/4-0/#!/example/locale/multi-lang.html 適當的語言修改腳本(/ EXT /本地/ ext-lang-xxx.js)需要在加載ext之後加載(包括動態加載的類)。在上面的例子中,我可能會使用Ext.Loader.loadScriptFile,但他們直接評估下載的一個。唯一的另一件事是你的類需要用不同的語言來構建,或者你只是使用變量並引用lang特定的變量文件。

你也可以在裝載路徑使用一個變量:

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

但是,這仍然意味着我需要一個大文件加載所有的翻譯結束,不是嗎?我想爲我的每個類(讓我們看看,每個視圖或每個控制器)都有語言環境文件。我實際上開發了一些東西,它可以工作,我也許應該在github上上傳它? – TigrouMeow

2

目前還沒有解決,所以我決定創建的Ext.Loader我自己的黑客/插件。我上傳了GitHub上的代碼:https://github.com/TigrouMeow/extjs-locale-loader。這正是我需要的,我真的希望它也能幫助別人!

+0

可以使用多種語言組合,當用戶更改組合值時,所有應用程序都會加載語言環境資源以更新語言?謝謝 –