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

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

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

Для пояснения: с помощью модификации реального 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 в себя переопределяющую папку и просто добавление этого файла в эту папку гарантирует, что применяется переопределение.

Interesting Posts

android sdk main.out.xml ошибка синтаксического анализа?

Статическая переменная шаблона

Почему темы не рекомендуются в .NET Reactive Extensions?

Как я могу заставить UITextField двигаться вверх, когда клавиатура присутствует?

Недавно я подключил внешний HD с eSATA в Windows 7. Когда я пытаюсь включить ReadyBoost, я нажимаю «Тест» в свойствах устройства и ничего не происходит. Зачем?

Архитектуры для доступа к смарт-карте из общего браузера? Или: как устранить разрыв между браузером и ПК / SC?

Многоуровневые таблицы (внутри другого при нажатии)

Обработка события Touch в UILabel и подключение его к IBAction

Можно ли установить ACL в точке монтирования sysfs?

Использование зарядного устройства с более высоким током на ноутбуке, для которого требуется более низкий ток

Как удалить RVM?

Можно ли зафиксировать отношения от 0..1 до 0..1 в Entity Framework?

Как получить диапазон занятых ячеек в листе excel

JavaFX Beans Binding внезапно перестает работать

Как получить размер объекта JavaScript?

Давайте будем гением компьютера.