我有一个Ext.form.field.Text
并且我想覆盖该setValue
功能。
在 ExtJS 中覆盖此类功能的推荐方法是什么?分机覆盖?
我有一个Ext.form.field.Text
并且我想覆盖该setValue
功能。
在 ExtJS 中覆盖此类功能的推荐方法是什么?分机覆盖?
澄清一下: 通过真正的类修改,我指的是对一个类的预期永久修改/扩展,这应该总是通过扩展一个类来完成。但这并不是针对特定问题(错误修复等)的临时解决方案。
您至少有四个选项如何覆盖(Ext)类的成员
我猜原型是众所周知的,它允许您覆盖类的所有实例的成员。你可以像这样使用它
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
此变体不应用于实际的类修改。
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)
用例:我遇到了一个(我认为仍然存在的)radiogroup 的不良行为,其中 ExtJS 期望一个对象(键值对)来正确设置值。但我的后端只有一个整数。我首先使用Ext.override对该
setValue()
方法进行了修复,然后从 radiogroup 扩展。在那里,我只是从给定的值创建一个键值对并用它调用父方法。
正如@rixo提到的,这可用于覆盖实例成员。因此可能有资格覆盖甚至混合(我自己从未测试过)
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;
}
});
这是一个JSFiddle
在极少数情况下会发生每个实例的覆盖,并且可能不适用于所有属性。在这种情况下(我手头没有示例),您只需要一种不同的行为,您可能会考虑仅针对每个实例覆盖一个设置。基本上,当您在类创建上应用配置时,您总是会做这些事情,但大多数时候您只是覆盖配置属性的默认值,但您也可以覆盖引用函数的属性。这完全覆盖了实现,您可能不允许访问基本类型(如果存在),这意味着您不能使用callParent
. 你可以试试setValue
看到它不能应用于现有的链。但同样,您可能会遇到一些有用的罕见情况,即使它只是在开发过程中并为了生产而重新实现。对于这种情况,您应该在使用Ext.override创建特定之后应用覆盖,如上所述。
重要提示:
this
如果您不使用Ext.override ,则无法通过调用访问类实例!
如果我遗漏了某些内容或某些内容(不再)正确,请发表评论或随时编辑。
这些方法都不允许您覆盖 mixins(例如 Ext.form.field.Field)。由于 mixin 函数在您定义类时被复制到类中,因此您必须直接将覆盖应用到目标类
@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 项目包含一个覆盖文件夹,只需将此文件添加到该文件夹即可确保应用覆盖。
这是在 ExtJS 7 中对我有用的唯一方法。
例子:
应用程序/桌面/覆盖/Toast.js
Ext.define(null, {
override: 'Ext.window.Toast',
show : function () {
this.callParent();
// Your custom code here...
}
});