在 ExtJS 中覆盖类/属性的最佳实践? [英] Best practice for overriding classes / properties in ExtJS?

查看:19
本文介绍了在 ExtJS 中覆盖类/属性的最佳实践?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 Ext.form.field.Text 并且我想覆盖 setValue 函数.

I have an Ext.form.field.Text and I want to override the setValue function.

在 ExtJS 中覆盖此类功能的推荐方法是什么?Ext.override?>

What is the recommended way to override this class functionality in ExtJS? Ext.override?

推荐答案

澄清:真正的类修改我的意思是一个预期的永久类的修改/扩展,应该始终通过扩展类来完成.但这不是针对特定问题(错误修复等)的临时解决方案.

For clarification: By real class modification I mean a intended permanent modification/extension of a class, which should always be done by extending a class. But it is not a temporary solution for just a specific problem (bug-fix, etc.).

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

You have at least four options how to override members of (Ext) Classes

  • prototype 我想这是众所周知的,它允许您覆盖一个类的所有实例的成员.你可以像

  • prototype I guess is well known and allows you to override a member for all instances of a class. You can use it like

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

虽然你不能像这样使用它

While you can't use it like

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

Here's a 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.覆盖 setValue()方法,然后从 radiogroup 扩展.在那里我只是做了一个来自给定值的键值对并调用父方法

Use case: I faced a (I think still existing) bad behavior of a radiogroup where ExtJS expect a object (key-value-pair) for correct setting of the value. But I have just one integer on my backend. I first applied a fix using Ext.override for the setValue() method and afterwards extend from radiogroup. There I just make a Key-Value-Pair from the given value and call the parent method with that.

正如 @rixo 提到的,这可用于覆盖实例成员.因此可能有资格覆盖甚至混合(我自己从未测试过)

As @rixo mentioned this can be used for overriding a instance member. And may therefore be qualified for overriding even mixins (I never tested it myself)

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

        this.callParent();
    }
});

这个变体不应用于真正的类修改.

扩展现有的类以应用额外的行为 &渲染.使用此变体创建行为不同的子类型,而不会丢失原始类型.

Extending a existent class to apply additional behavior & rendering. Use this variant to create a subtype that behaves different without loosing the original type.

在下面的示例中,我们使用一种方法扩展文本字段以在设置名为 setColored 的新值时更改标签颜色并覆盖 setValue 方法以确保直接调用setValue时去除标签颜色

In the following example we extend the textfield with a method to change the labelcolor when setting a new value called setColored and override the setValue method to take care of removing a label color when setValue is called directly

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

Here's a JSFiddle

覆盖每个实例 会在非常罕见的情况下发生,并且可能不适用于所有属性.在这种情况下(我手头没有示例),您只需要不同的行为,您可能会考虑仅覆盖每个实例的设置.基本上,当您在类创建上应用配置时,您总是会做这样的事情,但大多数时候您只是覆盖配置属性的默认值,但您也可以覆盖引用函数的属性.这完全覆盖了实现,您可能不允许访问基本类型(如果存在),这意味着您不能使用 callParent.您可以尝试使用 setValue 来查看它不能应用于现有链.但同样,您可能会遇到一些非常有用的罕见情况,即使它只是在开发过程中并被重新实现以提高生产力.对于这种情况,您应该在使用 Ext.override 如上所述.

Overriding per instance will happen in really rare cases and might not be applicable to all properties. In such a case (where I don't have a example at hand) you have a single need for a different behavior and you might consider overriding a setting just per instance. Basically you do such things all times when you apply a config on class creation but most time you just override default values of config properties but you are also able to override properties that references functions. This completely override the implementation and you might allows don't have access to the basetype (if any exist) meaning you cannot use callParent. You might try it with setValue to see that it cannot be applied to a existing chain. But again, you might face some rare cases where this is useful, even when it is just while development and get reimplemented for productive. For such a case you should apply the override after you created the specific by using Ext.override as mentioned above.

重要提示:如果您不使用 Ext.override!

如果我遗漏了某些内容或某些内容(不再)正确,请发表评论或随时进行编辑.

正如 @Eric

As commented by @Eric

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

None of these methods allow you to override mixins (such as Ext.form.field.Field). Since mixin functions are copied into classes at the time you define the class, you have to apply your overrides to the target classes directly

这篇关于在 ExtJS 中覆盖类/属性的最佳实践?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆