クラスのオーバーライド
今回はクラスのオーバーライドです。
クラスをオーバーライドすると、対象クラスのメソッドを上書きしたり、プロパティやメソッドを追加したりできます。
私がオーバーライドを使うのは↓のような場合です。
- フレームワークが提供しているクラスに不具合があり修正が必要・・・
- 良く使う機能を追加したい・・・
- 必ず含めないといけないリクエストパラメータを追加したい・・・
オーバーライドしてみる
試しにExt.form.field.Textをオーバーライドしてみましょう。
app.jsonには↓の定義があり、オーバーライド用のファイルはoverrides、classic/overrides、modern/overridesディレクトリに作成していきます。
"overrides": [ "overrides", "${toolkit.name}/overrides" ]
classicだけに適用したいので、classic/overridesにform/field/Text.jsを作成してみます。
最低限の記述は↓のようになります。overrideプロパティにオーバーライドしたいクラスを指定します。クラス名は何でも良いですが、私は大体、アプリケーション名.overrides.(オーバーライドするクラスのExtを除いた部分)とします。重複しないから。
/** * Ext.form.field.Textのオーバーライドクラス。 * * @class Memo.overrides.form.field.Text * @override Ext.form.field.Text */ Ext.define('Memo.overrides.form.field.Text', { override: 'Ext.form.field.Text' });
試しにpaddingを設定してみます。
/** * Ext.form.field.Textのオーバーライドクラス。 * * @class Memo.overrides.form.field.Text * @override Ext.form.field.Text */ Ext.define('Memo.overrides.form.field.Text', { override: 'Ext.form.field.Text', padding: 20 });
↓こんな感じにpaddingが反映されてますね。テキストエリアはExt.form.field.Textを継承しているので、そちらも影響を受けているのが分かります。
特定の機能を追加してみる
私がオーバーライドで良く作成する処理を1つ紹介します。入力フィールドをclearable: trueにすると、値が入力されるとクリアボタンが表示されるようにしています。
/** * Ext.form.field.Textのオーバーライドクラス。 * * @class Memo.overrides.form.field.Text * @override Ext.form.field.Text */ Ext.define('Memo.overrides.form.field.Text', { override: 'Ext.form.field.Text', /** * @cfg {Boolean} trueを設定するとクリア機能が利用できる。 */ clearable: false, // @override constructor: function(config) { var me = this; config = config || {}; if (config.clearable) { config.triggers = Ext.apply(config.triggers || {}, { clear: { weight: 0, cls: Ext.baseCSSPrefix + 'form-clear-trigger', hidden: true, handler: 'onClearClick', scope: 'this' } }) } me.callParent(arguments); if (config.clearable) { me.on('change', 'onChange', me); } }, // @override afterRender: function(){ var me = this; me.callParent(); me.onChange(); }, /** * クリアボタンクリック時の処理。 */ onClearClick : function(){ this.setValue(''); }, /** * changeイベント発火時の処理。 */ onChange: function() { var me = this, value = String(me.getValue() || ''); value.length > 0 ? me.showClearButton() : me.hideClearButton(); }, /** * クリアボタンを表示する */ showClearButton: function() { var me = this; if(me.triggers.clear) { me.triggers.clear.show(); } }, /** * クリアボタンを非表示にする */ hideClearButton: function() { var me = this; if(me.triggers.clear) { me.triggers.clear.hide(); } } });
便利な機能の1つだと思いますが、継承しているクラスにも影響するので、オーバーライドしても大丈夫か注意して使うようにしましょう。