5

ExtJSアプリケーションを別の言語に翻訳したいと思います。私の問題は、ExtJS MVCフレームワークを使用していて、ほとんどのJSファイルがフレームワーク自体によって動的にダウンロードされることです。

(私が考えた)理想的な解決策は、Ext.Loader(または私のExt.app.Application)に、使用する言語を定義する追加のオプションを用意し、これに応じて「 「a.MyClass.js」をロードした後の「a.MyClass.fr.js」(これにはExt.applyが含まれ、文字列リソースをオーバーライドします)。現時点では、ExtJSフレームワークではおそらく利用できません。

私が見ることができる別の解決策は、サーバー側でトリックを実行することです。まず、言語に設定するために、クライアント上にCookieが作成されます。サーバー側では、JSファイルへのすべてのリクエストをキャッチできます。次に、Cookieが設定されている場合(='fr'など)、リクエストされたJSファイル(MyClass.js)とそのi18nのフレンド(MyClass)を結合します。 .fr.js)をサーバー上で動的に実行し、結果を返します。それはうまくいくでしょうが、それは他のことを暗示しているので本当にトリッキーです(キャッシング...)。

おそらく最良の方法は、ExtJSフレームワークで説明した最初の動作を自分で実装することです...

どう思いますか?私はそれを行うための本当にきれいできれいな方法を探しています!ありがとう :)

4

4 に答える 4

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=ファイルのコピーなど。

長所:

  • 手間のかからないコード'Your_key'.translate()を使用すると、これがローカライズされた文字列であることを読みやすく、認識しやすくなります。
  • メンテナンスのオーバーヘッドなし/わずか(ロケールごとにオーバーライドファイルを保持しますか?イエス..)
  • シャバン全体ではなく、必要なロケールのみをロードします。
  • 本当に必要な場合は、同じバンドル内のExtJSロケールファイルの独自の翻訳を作成することもできます。
  • 単体テストを記述して、すべてのバンドルに同じキーが含まれていることを確認し、後で孤立した翻訳を回避することができます。

短所:

  • 同期-メインアプリを起動する前にストアをロードする必要があります。すべてのテキストが読み込まれると呼び出されるユーティリティクラスからのコールバックを追加することで、これを解決しました。
  • リアルタイムのテキストの入力はありません..ユーザーにサーバーを過負荷にさせたくありませんでしたが:P

これまでのところ、私のアプローチは私の要件に対してかなりうまく機能しています。サイトの読み込みはそれほど遅くはなく、バンドル(バンドルごとに最大200のキー/値を含む)は読み込み中に最大10kbで測定されます。

于 2011-10-19T12:46:46.953 に答える
2

現在、解決策がないため、Ext.Loaderで独自のハック/アドオンを作成することにしました。コードをGitHubにアップロードしました:https ://github.com/TigrouMeow/extjs-locale-loader 。それはまさに私が必要としていたものであり、それが他の人にも役立つことを本当に望んでいます!

于 2011-09-05T00:49:17.190 に答える
0

最初に開発フェーズを完了してプロジェクトをビルドするか、ext-all.jsファイルを使用してUIをI18に変換する必要があります

于 2011-08-29T11:58:36.127 に答える
0

参照: http: //docs.sencha.com/ext-js/4-0/# !/ example / locale / multi-lang.html適切な言語修飾子スクリプト(/ext/local/ext-lang-xxx.js )extがロードされた後にロードする必要があります(動的にロードされるクラスを含む)。上記の例では、おそらくExt.Loader.loadScriptFileを使用していましたが、ダウンロードしたものを直接評価します。他の唯一のことは、クラスを異なる言語で構築する必要があるか、変数を使用してlang固有の変数ファイルを参照するだけであるということです。

ローダーパスで変数を使用することもできます。

var lang='fr';
Loader
{
 paths:
 {
    'Ext': '.',  
    'My': './src/my_own_folder'+'/'+lang
 }
于 2011-09-01T04:38:45.400 に答える