Подтвердить что ты не робот

Лучшая практика для переопределения классов/свойств в ExtJS?

У меня есть Ext.form.field.Text, и я хочу переопределить функцию setValue.

Каков рекомендуемый способ переопределить эту функциональность класса в ExtJS? Ext.override?

4b9b3361

Ответ 1

Для уточнения: модификация реального класса Я имею в виду предполагаемый постоянный модификация/расширение класса, что всегда должно быть сделано путем расширения класса. Но это не временное решение только для конкретной проблемы (исправление ошибок и т.д.).

У вас есть как минимум четыре варианта переопределения членов классов (Ext)

  • прототип Я думаю, хорошо известно и позволяет переопределить элемент для всех экземпляров класса. Вы можете использовать его как

    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 ожидает, что объект (пара ключ-значение) для правильного установка значения. Но у меня есть только одно целое на моем бэкэнде. я сначала применили исправление, используя Ext.override для setValue()метод, а затем простирается от радиогруппы. Там я просто Параметр Key-Value-Pair из заданного значения и вызов родительского метода с помощью что.

    Как указано @rixo, это можно использовать для переопределения члена экземпляра. И поэтому может быть квалифицирован для переопределения даже миксинов (я никогда не тестировал его сам)

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

    Этот вариант не должен использоваться для модификаций реального класса.

  • Расширение существующего класса для применения дополнительного поведения и рендеринга. Используйте этот вариант для создания подтипа, который ведет себя по-другому, не теряя исходного типа.

    В следующем примере мы расширяем текстовое поле с помощью метода изменения цвета метки при установке нового значения setColored и переопределяем метод setValue, чтобы позаботиться об удалении цвета ярлыка, когда setValue вызывается непосредственно

    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

  • Переопределение на один экземпляр произойдет в очень редких случаях и может не применимо ко всем свойствам. В таком случае (где у меня нет примера) у вас есть одна потребность в другом поведении, и вы можете рассмотреть возможность переопределения параметра только для каждого экземпляра. В основном вы делаете такие вещи все время, когда вы применяете конфигурацию при создании класса, но в большинстве случаев вы просто переопределяете значения параметров по умолчанию, но вы также можете переопределить свойства, ссылающиеся на функции. Это полностью переопределяет реализацию, и вы можете запретить доступ к базовому типу (если таковой существует), что означает, что вы не можете использовать callParent. Вы можете попробовать с помощью setValue увидеть, что он не может быть применен к существующей цепочке. Но опять же, вы можете столкнуться с некоторыми редко встречающимися случаями, когда это полезно, даже когда оно просто развивается и становится переоцененным для продуктивности. Для такого случая вы должны применить переопределение после создания конкретного с помощью Ext.override, как указано выше.

    Важно: У вас нет доступа к экземпляру класса, вызывая this, если вы не используете Ext.override!

Если я пропустил что-то или что-то (больше не работает) правильно, прокомментируйте или отредактируйте свободно.

Как прокомментировано @Eric

Ни один из этих методов не позволяет вам переопределить mixins (например, Ext.form.field.Field). Поскольку функции mixin копируются в классы во время определения класса, вам необходимо непосредственно применить свои переопределения к целевым классам.

Ответ 2

Ответ от @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)
    }
});

Я все еще использую Ext 5, поэтому я загрузил бы этот файл в свой Application.js и добавлю его в требуемый массив, который применит переопределение к приложению по всему миру. Я думаю, что проекты Ext 6 включают в себя переопределяющую папку и просто добавление этого файла в эту папку обеспечивает применение переопределения.