32

があり、関数Ext.form.field.Textをオーバーライドしたい。setValue

ExtJSでこのクラス機能をオーバーライドするための推奨される方法は何ですか?Ext.override

4

3 に答える 3

78

明確にするために:実際のクラス変更とは、クラスの意図された永続的な変更/拡張を意味します。 これは、常にクラスを拡張することによって実行する必要があります。ただし、特定の問題(バグ修正など)の一時的な解決策ではありません。

(Ext)クラスのメンバーをオーバーライドする方法には少なくとも4つのオプションがあります

  • プロトタイプはよく知られていると思いますが、クラスのすべてのインスタンスのメンバーをオーバーライドできます。あなたはそれを次のように使うことができます

    Ext.view.View.prototype.emptyText = "";
    

    あなたはそれをのように使うことはできませんが

    // callParent is NOT allowed for prototype
    Ext.form.field.Text.prototype.setValue = function(val) {
        var me = this,
            inputEl = me.inputEl;
    
        if (inputEl && me.emptyText && !Ext.isEmpty(value)) {
            inputEl.removeCls(me.emptyCls);
            me.valueContainsPlaceholder = false;
        }
    
        me.callParent(arguments);
    
        me.applyEmptyText();
        return me;
    };
    

    これがJSFiddleです

    このバリアントは、実際のクラスの変更には使用しないでください。

  • Ext.overrideは、プロトタイプとほぼ同じように動作しますが、ExtJSクラスシステムに完全に適用されます。callParent()

    あなたはそれを次のように使うことができます

    // callParent is allowed for override
    Ext.override('Ext.form.field.Text', {
        setValue: function(val) {
            this.callParent(['In override']);
            return this;
        }
    });
    

    これがJSFiddleです(cpエラーが修正されました!@nogridbagに感謝します)

    ユースケース: ExtJSが値の正しい設定のためにオブジェクト(キーと値のペア)を期待するラジオグループの(まだ存在していると思う)悪い動作に直面しました。しかし、バックエンドには整数が1つしかありません。最初にメソッドにExt.overrideを使用して修正を適用しsetValue() 、その後ラジオグループから拡張しました。そこで、指定された値からKey-Value-Pairを作成し、それを使用して親メソッドを呼び出します。

    @rixoが述べたように、これはインスタンスメンバーをオーバーライドするために使用できます。したがって、ミックスインでさえオーバーライドする資格があるかもしれません(私はそれを自分でテストしたことはありません)

    var panel = new Ext.Panel({ ... });
    Ext.override(panel, {
        initComponent: function () {
            // extra processing...
    
            this.callParent();
        }
    });
    

    このバリアントは、実際のクラスの変更には使用しないでください。

  • 既存のクラスを拡張して、追加の動作とレンダリングを適用します。このバリアントを使用して、元のタイプを失うことなく異なる動作をするサブタイプを作成します。

    次の例では、呼び出された新しい値を設定するときにラベルの色を変更するメソッドでテキストフィールドを拡張し、が直接呼び出されたときにラベルの色を削除するようにメソッドをsetColoredオーバーライドしますsetValuesetValue

    Ext.define('Ext.ux.field.Text',{
        extend: 'Ext.form.field.Text',
        widget: 'uxtextfield',
        setColored: function(val,color) {
            var me = this;
            if (me.settedCls) {
                me.removeCls(me.settedCls);
            }
            me.addCls(color);
            me.settedCls = color;
            me.setValue(val,true);
        },
        setValue: function(val,take) {
            var me = this;
            if (!take && me.settedCls) {
                me.removeCls(me.settedCls);
            }
            me.callParent(arguments);
            return me;
        }
    });
    

    これがJSFiddleです

  • インスタンスごとのオーバーライドは非常にまれなケースで発生し、すべてのプロパティに適用できるとは限りません。このような場合(手元に例がない場合)、異なる動作が1つ必要であり、インスタンスごとに設定をオーバーライドすることを検討できます。基本的に、クラスの作成時に構成を適用するときは常にそのようなことを行いますが、ほとんどの場合、構成プロパティのデフォルト値をオーバーライドするだけですが、関数を参照するプロパティをオーバーライドすることもできます。これは実装を完全にオーバーライドし、ベースタイプ(存在する場合)へのアクセスを許可しない可能性があります。つまり、を使用できませんcallParent。あなたはそれを試してみるかもしれませんsetValue既存のチェーンに適用できないことを確認します。しかし、繰り返しになりますが、開発中であっても、生産性を高めるために再実装された場合でも、これが役立つまれなケースに直面する可能性があります。このような場合は、上記のようにExt.overrideを使用して特定のものを作成した後で、オーバーライドを適用する必要があります。

    重要:Ext.overridethisを使用しない場合は、を呼び出してクラスインスタンスにアクセスすることはできません。

私が何かを見逃したり、何かが(もはや)正しくない場合は、コメントするか、自由に編集してください。

@Ericによるコメント

これらのメソッドのいずれも、ミックスイン(Ext.form.field.Fieldなど)をオーバーライドすることはできません。ミックスイン関数はクラスを定義するときにクラスにコピーされるため、オーバーライドをターゲットクラスに直接適用する必要があります

于 2013-01-10T09:33:37.277 に答える
3

@sraによる回答は素晴らしく、Extで利用可能なオーバーライド機能をより深く理解するのに非常に役立ちましたが、次のようなオーバーライドを最も一般的に実装する方法は含まれていません。

Ext.define('my.application.form.field.Text' {
    override: 'Ext.form.field.Text'
    getValue: function () {
        // your custom functionality here
        arguments[1] = false;

        // callParent can be used if desired, or the method can be 
        // re-written without reference to the original
        this.callParent(arguments)
    }
});

私はまだExt5を使用しているので、このファイルを自分のファイルにロードApplication.jsして、アプリにオーバーライドをグローバルに適用するrequires配列に追加します。Ext 6プロジェクトにはオーバーライドフォルダーが含まれていると思います。このファイルをそのフォルダーに追加するだけで、オーバーライドが確実に適用されます。

于 2017-05-05T22:52:46.647 に答える
1

これは、ExtJS7で機能する唯一の方法です。

例:

app / desktop / overrides / Toast.js

Ext.define(null, {
    override: 'Ext.window.Toast',
    show : function () {
        this.callParent();
// Your custom code here...
    }
});
于 2021-06-19T08:43:44.477 に答える