Лучшая практика для переопределения classов / свойств в ExtJS?
У меня есть Ext.form.field.Text
и я хочу переопределить функцию setValue
.
Каков рекомендуемый способ переопределить эту функциональность classа в ExtJS? Ext.override ?
- Может ли java вызвать родительский переопределенный метод в других объектах, но не подтип?
- В чем разница между перегрузкой и переопределением метода?
- Зачем нам нужно новое ключевое слово и почему поведение по умолчанию скрывается и не отменяется?
- Переопределение переменных-членов в Java
- Android Overriding onBackPressed ()
- Почему нам нужно переопределить метод equals () в Java?
- Небольшая путаница в отношении переопределения переменных.
- Пользовательский ImageView с тенью
- Переопределение GetHashCode для изменяемых объектов?
- Какие проблемы следует учитывать при переопределении равных и hashCode в Java?
- Класс не является абстрактным и не отменяет ошибку в Java
- Почему / когда было бы целесообразно переопределить ToString?
Для пояснения: с помощью модификации реального classа я имею в виду предполагаемую постоянную модификацию / расширение classа , которая всегда должна выполняться путем расширения classа. Но это не временное решение только для конкретной проблемы (исправление ошибок и т . Д.) .
У вас есть как минимум четыре варианта переопределения членов (Ext) classов
-
прототип, я думаю, хорошо известен и позволяет вам переопределить элемент для всех экземпляров classа. Вы можете использовать его как
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
Этот вариант не должен использоваться для модификаций реального classа.
-
Ext.override делает почти тот же прототип, но полностью применим к системе classа 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()
а затем – из радиогруппы. Там я просто делаю ключ-значение-пар из заданного значения и вызываю родительский метод с этим.Как упоминал @rixo, это можно использовать для переопределения члена экземпляра. И поэтому может быть квалифицирован для переопределения даже миксинов (я никогда не тестировал его сам)
var panel = new Ext.Panel({ ... }); Ext.override(panel, { initComponent: function () { // extra processing... this.callParent(); } });
Этот вариант не должен использоваться для модификаций реального classа.
-
Расширение существующего classа для применения дополнительного поведения и рендеринга. Используйте этот вариант для создания подтипа, который ведет себя по-другому, не теряя исходный тип.
В следующем примере мы расширяем текстовое поле с помощью метода изменения цвета метки при установке нового значения, называемого
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
-
Переопределение на один экземпляр произойдет в очень редких случаях и может быть неприменимо ко всем свойствам. В таком случае (где у меня нет примера) у вас есть одна потребность в другом поведении, и вы можете рассмотреть возможность переопределения параметра только для каждого экземпляра. В основном вы делаете такие вещи все время, когда вы применяете конфигурацию при создании classа, но в большинстве случаев вы просто переопределяете значения параметров по умолчанию, но вы также можете переопределить свойства, ссылающиеся на функции. Это полностью отменяет реализацию, и вы можете запретить доступ к базовому типу (если таковой существует), что означает, что вы не можете использовать
callParent
. Вы можете попробовать его с помощьюsetValue
чтобы убедиться, что он не может быть применен к существующей цепочке. Но опять же, вы можете столкнуться с некоторыми редко встречающимися случаями, когда это полезно, даже когда оно просто развивается и становится переоцененным для продуктивности. Для такого случая вы должны применить переопределение после создания конкретного с помощью Ext.override, как указано выше.Важно: у вас нет доступа к экземпляру classа, вызвав
this
если вы не используете Ext.override !
Если я пропустил что-то или что-то (больше не) правильно, прокомментируйте или не стесняйтесь редактировать.
Как прокомментировал @Eric
Ни один из этих методов не позволяет вам переопределить mixins (например, Ext.form.field.Field). Поскольку функции mixin копируются в classы во время определения classа, вам необходимо применить свои переопределения к целевым classам напрямую
Ответ от @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 include в себя переопределяющую папку и просто добавление этого файла в эту папку гарантирует, что применяется переопределение.