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

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

问题描述

我有一个 Ext.form.field.Text ,我想覆盖 setValue 函数。 p>

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

解决方案


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


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




  • / strong>我猜是很有名的,允许你覆盖一个类的所有实例的一个成员。你可以使用它像

      Ext.view.View.prototype.emptyText =; 

    虽然您不能像

      // callParent不允许用于原型
    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();
    回报我
    };

    这是一个 JSFiddle



    此变体不应用于实际类修改。 / strong>


  • Ext.override 与原型几乎相同,但它完全适用于ExtJS类系统,允许您使用 callParent()



    您可以使用它像

      // callParent被允许覆盖
    Ext.override('Ext.form.field.Text',{
    setValue:function(val){
    this。 callParent(['In override']);
    return this;
    }
    });

    这是一个 JSFiddle (cp错误修复!感谢 @nogridbag


    用例:我遇到一个(我认为还存在)一个
    radiogroup,其中ExtJS期望一个对象(键值对)用于正确的
    值的设置。但是我的后端只有一个整数。 I
    首先使用 Ext.override setValue()
    方法,然后从radiogroup扩展。在那里,我只需要从给定的值中创建一个
    Key-Value-Pair,并使用
    调用父方法。


    @rixo 所述,这可以用于覆盖实例成员。因此可能有资格覆盖甚至混合(我从来没有测试过)

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

    this.callParent();
    }
    });

    此变体不应用于实际类修改。


  • 扩展一个现有的类来应用其他行为&渲染。使用此变体可以创建一个不同的原型,而不会丢失原始类型的子类型。



    在下面的示例中,我们使用一个方法来扩展textfield以更改labelcolor设置一个名为 setColored 的新值,并覆盖 setValue 方法,以便在<$ c $时删除标签颜色c> setValue 直接调用

      Ext.define('Ext.ux。 field.Text',{
    extends:'Ext.form.field.Text',
    widget:'uxtextfield',
    setColored:function(val,color){
    var me = this;
    if(me.settedCls){
    me.removeCls(me.settedCls);
    }
    me.addCls(color);
    我。 settedCls = color;
    me.setValue(val,true);
    },
    setValue:function(val,take){
    var me = this;
    if (!take&& me.settedCls){
    me.removeCls(me.settedCls);
    }
    me.callParent(arguments);
    回报我
    }
    });

    这是一个 JSFiddle


  • 覆盖每个实例在极少数情况下,可能不适用于所有属性。在这种情况下(我手头上没有示例),您只需要一个不同的行为,您可以考虑覆盖每个实例的设置。基本上,当您在类创建时应用配置时,您都可以执行此类操作,但大多数情况下,您只需覆盖配置属性的默认值,但您也可以覆盖引用函数的属性。这完全覆盖了实现,您可能允许无权访问basetype(如果有的话)意味着您不能使用 callParent 。您可以尝试使用 setValue 来查看它不能应用于现有的链。但是,再次,您可能会遇到一些罕见的情况,即使在发展和重新实现生产力的同时,这是有用的。对于这种情况,您应该使用 Ext.override 如上所述。


    重要提示:你如果您不使用此访问类实例/ 4-1 /#!/ api / Ext-method-overriderel =nofollow noreferrer> Ext.override





如果我错过了某些东西或某事(不再)正确,请评论或随意修改。



@Eric 评论strong>



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


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

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.).

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

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

    Here's a JSFiddle

    This variant should not be used for real class modifications.

  • Ext.override does nearly the same then prototype but it fully applies to the ExtJS Class-system which allows you to use callParent()

    You can use it like

    // callParent is allowed for override
    Ext.override('Ext.form.field.Text', {
        setValue: function(val) {
            this.callParent(['In override']);
            return this;
        }
    });
    

    Here's a JSFiddle (c-p error fixed! Thanks to @nogridbag)

    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.

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

    This variant should not be used for real class modifications.

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

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

    Here's a JSFiddle

  • 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.

    Important: You don't have access to the class-instance by calling this if you don't use Ext.override!

If I missed something or something is (no longer) correct, please comment or feel free to edit.

As commented by @Eric

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天全站免登陆