webentwicklung-frage-antwort-db.com.de

Best Practice zum Überschreiben von Klassen/Eigenschaften in ExtJS?

Ich habe einen Ext.form.field.Text und möchte die setValue-Funktion überschreiben.

Was ist die empfohlene Methode, um diese Klassenfunktionalität in ExtJS zu überschreiben? Ext.override ?

29
A1rPun

Zur Verdeutlichung: Mit echte Klassenänderung meine ich beabsichtigte dauerhafte Änderung/Erweiterung einer Klasse, was immer getan werden sollte durch eine Klasse erweitern. Aber es ist nicht eine vorübergehende Lösung für nur ein bestimmtes Problem (Bugfix usw.).

Sie haben mindestens vier Möglichkeiten, wie Sie Mitglieder von (Ext) -Klassen überschreiben können

  • Prototyp Ich schätze, es ist bekannt und erlaubt Ihnen, ein Mitglied für alle Instanzen einer Klasse zu überschreiben. Du kannst es gerne benutzen

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

    Während Sie es wie nicht verwenden können

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

    Hier ist ein JSFiddle

    Diese Variante sollte nicht für echte Klassenänderungen verwendet werden.

  • Ext.override funktioniert fast genauso wie der Prototyp, aber es gilt vollständig für das ExtJS-Klassensystem, mit dem Sie callParent() verwenden können.

    Du kannst es gerne benutzen

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

    Hier ist ein JSFiddle (c-p Fehler behoben! Danke an @ nogridbag )

    se case: Ich habe ein (meiner Meinung nach noch vorhandenes) schlechtes Verhalten einer Funkgruppe festgestellt, bei dem ExtJS ein Objekt (Schlüssel-Wert-Paar) zur korrekten Einstellung des Werts erwartet. Aber ich habe nur eine ganze Zahl in meinem Backend. Ich habe zuerst einen Fix mit Ext.override für die Methode setValue() angewendet und danach von der Radiogruppe aus erweitert. Dort erstelle ich aus dem angegebenen Wert ein Schlüssel-Wert-Paar und rufe damit die übergeordnete Methode auf.

    Wie @ rixo erwähnt, kann dies zum Überschreiben eines Instanzmitglieds verwendet werden. Und kann daher für das Überschreiben auch Mixins qualifiziert sein (ich habe es selbst nie getestet)

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

    Diese Variante sollte nicht für echte Klassenänderungen verwendet werden.

  • Extending Eine vorhandene Klasse, um zusätzliches Verhalten und Rendering anzuwenden. Verwenden Sie diese Variante, um einen Untertyp zu erstellen, der sich anders verhält, ohne den ursprünglichen Typ zu verlieren.

    Im folgenden Beispiel erweitern wir das Textfeld um eine Methode zum Ändern der Beschriftungsfarbe, wenn ein neuer Wert mit dem Namen setColored festgelegt wird, und überschreiben die Methode setValue, um das Entfernen einer Beschriftungsfarbe zu gewährleisten wenn setValue direkt aufgerufen wird

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

    Hier ist ein JSFiddle

  • Überschreiben pro Instanz tritt in sehr seltenen Fällen auf und ist möglicherweise nicht auf alle Eigenschaften anwendbar. In einem solchen Fall (in dem ich kein Beispiel zur Hand habe) müssen Sie sich nur einmal anders verhalten, und Sie könnten in Betracht ziehen, eine Einstellung nur für eine Instanz zu überschreiben. Grundsätzlich tun Sie dies immer dann, wenn Sie eine Konfiguration bei der Klassenerstellung anwenden. Meistens überschreiben Sie jedoch nur die Standardwerte der Konfigurationseigenschaften. Sie können jedoch auch Eigenschaften überschreiben, die auf Funktionen verweisen. Dies überschreibt die Implementierung vollständig und Sie können möglicherweise zulassen, dass Sie keinen Zugriff auf den Basistyp haben (falls vorhanden), was bedeutet, dass Sie callParent nicht verwenden können. Sie können es mit setValue versuchen, um festzustellen, dass es nicht auf eine vorhandene Kette angewendet werden kann. Es kann jedoch auch vorkommen, dass dies in einigen seltenen Fällen nützlich ist, selbst wenn die Entwicklung noch nicht abgeschlossen ist und Sie für produktive Zwecke erneut implementiert werden. In einem solchen Fall sollten Sie die Außerkraftsetzung anwenden, nachdem Sie die spezifische mit Ext.override wie oben erwähnt erstellt haben.

    Wichtig: Sie haben keinen Zugriff auf die Klasseninstanz, indem Sie this aufrufen, wenn Sie Ext.override nicht verwenden!

Wenn ich etwas verpasst habe oder etwas (nicht mehr) korrekt ist, kommentiere es bitte oder bearbeite es.

Wie von @ Eric kommentiert

Bei keiner dieser Methoden können Sie Mixins überschreiben (z. B. Ext.form.field.Field). Da Mixin-Funktionen zum Zeitpunkt der Definition der Klasse in Klassen kopiert werden, müssen Sie Ihre Überschreibungen direkt auf die Zielklassen anwenden

75
sra

Die Antwort von @sra ist großartig und hat mir sehr geholfen, ein tieferes Verständnis der in Ext verfügbaren Überschreibungsfunktionalität zu erlangen. Es enthält jedoch nicht die Art und Weise, wie ich Überschreibungen am häufigsten implementiere.

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

Ich benutze immer noch Ext 5, also lade ich diese Datei in meinen Application.js und füge sie dort dem Requires-Array hinzu, das die Überschreibung auf die App global anwendet. Ich denke, Ext 6-Projekte enthalten einen Überschreibungsordner. Durch einfaches Hinzufügen dieser Datei wird sichergestellt, dass die Überschreibung angewendet wird.

1
Grant Humphries