在ExtJS中重写类/属性的最佳实践是什么?

ajsxfq5m  于 2022-11-04  发布在  其他
关注(0)|答案(3)|浏览(203)

我有一个Ext.form.field.Text,我想覆盖setValue函数。
在ExtJS中重写该类功能的推荐方法是什么?

dtcbnfnu

dtcbnfnu1#

  • 澄清一下:真实的的类修改我的意思是一个类的永久修改/扩展,这应该总是通过扩展一个类来完成。但它不是一个特定问题的临时解决方案(bug修复等)

您至少有四个选项可以选择如何覆盖(Ext)类的成员

*prototype我想这是众所周知的,它允许你为一个类的所有示例重写一个成员。

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

这里有一个

此变量不应用于真实的类修改。
*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**(c-p错误已修复!感谢@nogridbag)

用例:我遇到了一个(我认为仍然存在)radiogroup的坏行为,其中ExtJS需要一个对象(键-值-对)来正确设置值。但我的后端只有一个整数。我首先使用Ext.overridesetValue()方法应用了一个修复,然后从radiogroup扩展。我只是从给定的值创建了一个键-值-对,并用它调用父方法。
正如@rixo提到的,这可以用于覆盖示例成员。因此,什至可以用于覆盖mixin(我自己从未测试过)

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

这里有一个

*覆写每个执行严修只会在极少数情况下发生,而且可能不适用于所有属性。在这种情况下(我手边没有示例)您只需要一个不同的行为,您可能会考虑覆盖每个示例的设置。基本上,在创建类时应用配置时,您一直都在做这样的事情,但大多数情况下,您只是覆盖配置属性的默认值但是你也可以覆盖引用函数的属性。这完全覆盖了实现,你可能无法访问基类型(如果有的话),这意味着您不能使用callParent。您可以尝试使用setValue,看看它是否不能应用于现有的链。但是,您可能会遇到一些罕见的情况,这是有用的,即使是在开发的时候,为了生产需要重新实现。对于这样的情况,你应该在创建了特定的覆盖之后使用Ext.override来应用覆盖,如上所述。
**重要提示:**如果不使用Ext.override,则无法通过调用this访问类示例!
如果我遗漏了某些内容或某些内容(不再)正确,请评论或随时编辑。
@Eric评论

这些方法都不允许覆盖混合函数(如Ext.form.field.Field)。由于混合函数是在定义类时复制到类中的,因此必须将覆盖直接应用于目标类

qvsjd97n

qvsjd97n2#

@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中加载这个文件,并将其添加到requires数组中,从而将覆盖全局应用到应用程序。我认为Ext 6项目包含一个覆盖文件夹,只需将此文件添加到该文件夹中即可确保覆盖得到应用。

相关问题