多言語対応[classic]
今回は言語の切り替えを試してみます。
おおまかなポイントを列挙しました。
- 言語はプルダウンで選択する
- 選択した言語はローカルストレージで保持する
- ロケールファイルをロードしてから、ビューを作成する
app.jsonの修正
localeの定義は消します。
ext-localeのrequireは残します。
言語はプルダウンで選択する
まずは言語選択用のプルダウンを設置します。
/** * メインパネル。 * * @class Sample.view.main.Panel * @extend Ext.panel.Panel */ Ext.define('Sample.view.main.Panel', { extend: 'Ext.panel.Panel', xtype: 'main_panel', requires: [ 'Ext.picker.Date' ], title: '多言語対応', tools: [ { xtype: 'combo', displayField: 'text', valueField: 'value', queryMode: 'local', editable: false, forceSelection: true, store: { fields: ['text', 'value'], data: [ {'text': 'English', 'value': 'en'}, {'text': '日本語', 'value': 'ja'} ] } } ], items: [ { xtype: 'datepicker' } ] });
選択した言語はローカルストレージで保持する
ビューコントローラを追加し、言語プルダウンを変更したらローカルストレージに保存するようにします。
/** * メインパネル。 * * @class Sample.view.main.Panel * @extend Ext.panel.Panel */ Ext.define('Sample.view.main.Panel', { extend: 'Ext.panel.Panel', xtype: 'main_panel', requires: [ 'Ext.picker.Date', 'Sample.view.main.ViewController' ], controller: 'main', title: '多言語対応', tools: [ { xtype: 'combo', displayField: 'text', valueField: 'value', queryMode: 'local', editable: false, forceSelection: true, store: { fields: ['text', 'value'], data: [ {'text': 'English', 'value': 'en'}, {'text': '日本語', 'value': 'ja'} ] }, value: Ext.util.LocalStorage.get('sample').getItem('locale') || 'en', listeners: { change: 'onChangeLocaleCombo' } } ], items: [ { xtype: 'datepicker' } ] }); /** * ビューコントローラクラス。 * * @class Sample.view.main.ViewController * @extend Ext.app.ViewController */ Ext.define('Sample.view.main.ViewController', { extend: 'Ext.app.ViewController', alias: 'controller.main', requires: [ 'Ext.util.LocalStorage' ], /** * 言語プルダウンchangeイベント時の処理。 * * @param {Ext.form.field.Combo} field プルダウン * @param {String} value 値 */ onChangeLocaleCombo: function (field, value) { var store = Ext.util.LocalStorage.get('sample'), currentLocale = store.getItem('locale'); if (currentLocale !== value) { store.setItem('locale', value); window.location.reload(); } } });
これでローカルストレージに選択した言語が保存されます。
保存後は、ロケールファイルをロードするために、window.location.reloadでブラウザをリロードさせます。
ロケールファイルをロードしてから、ビューを作成する
ここからはApplication.jsを修正していきます。
まずはapp.jsのmainViewを削除します。mainViewにはビューポートとなるコンポーネントを定義していますが、これが定義されているとロケールファイルをロードする前にビューが作成されてしまうためです。
とりあえずコメントアウトしました。
/* * This file is generated and updated by Sencha Cmd. You can edit this file as * needed for your application, but these edits will have to be merged by * Sencha Cmd when upgrading. */ Ext.application({ name: 'Sample', extend: 'Sample.Application', requires: [ 'Sample.view.main.Panel' ] // The name of the initial view to create. With the classic toolkit this class // will gain a "viewport" plugin if it does not extend Ext.Viewport. With the // modern toolkit, the main view will be added to the Viewport. // //mainView: 'Sample.view.main.Panel' //------------------------------------------------------------------------- // Most customizations should be made to Sample.Application. If you need to // customize this file, doing so below this section reduces the likelihood // of merge conflicts when upgrading to new versions of Sencha Cmd. //------------------------------------------------------------------------- });
次にApplication.jsでロケールファイルをロードします。
/** * アプリケーションクラス。 * * @class Sample.Application * @extend Ext.app.Application */ Ext.define('Sample.Application', { extend: 'Ext.app.Application', name: 'Sample', requires: [ 'Ext.util.LocalStorage' ], /** * ローンチ処理。 */ launch: function () { var me = this; me.loadLocaleFile(function () { me.setMainView('Sample.view.main.Panel'); }); }, /** * ロケールファイルをロードする。 * @param {Function} [cb] コールバック */ loadLocaleFile: function (cb) { var me = this, store = Ext.util.LocalStorage.get('sample'), locale = store.getItem('locale') || 'en'; Ext.Loader.loadScript({ url: me.getLocaleUrl(locale), onLoad: function () { if (cb) { cb(); } } }); }, /** * ロケールファイルのURLを返す。 * * @param {String} locale 言語名 * @returns {String} ロケールファイルのURL */ getLocaleUrl: function (locale) { // MEMO: プロジェクト毎のロケールファイルのパスを設定する return '/ext/classic/locale/overrides/' + locale + '/ext-locale-' + locale + '.js'; } });
ロケールファイルをロードした後に、Ext.ApplicationのsetMainViewを呼び出すことで順番を担保しています。
ちなみに上記コードでは、ロケールファイルのパスはサンプル用なので、実際には適宜変更することになります。開発環境や本番環境で差異がある場合もあるでしょう。
良い感じになりました。
補足
これはあくまでも一例です。
ロケールファイルをロードできれば良いだけなので、scriptタグでロードしようが、JQueryでロードしようが、どういう方法でやっても問題ありません。