我有一个Ext.form.field.Text
,我想覆盖setValue
函数。
在ExtJS中覆盖此类功能的推荐方法是什么? Ext.override?
答案 0 :(得分:74)
澄清: 通过真实的类修改我的意思是一个预期的永久性 修改/扩展类,应始终通过扩展类来完成。 但它不是仅针对特定问题的临时解决方案(错误修复等)。
至少有四个选项可以覆盖(Ext)Classes的成员
原型我想众所周知,并且允许您覆盖类的所有实例的成员。您可以像
一样使用它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 与原型几乎完全相同,但它完全适用于允许您使用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.override 为
setValue()
应用修补程序 方法然后从radiogroup延伸。在那里,我只是做了一个 Key-Value-Pair来自给定值并使用父方法调用 这一点。
提到@rixo这可以用来覆盖实例成员。因此可能有资格覆盖甚至mixins(我从未自己测试过)
var panel = new Ext.Panel({ ... });
Ext.override(panel, {
initComponent: function () {
// extra processing...
this.callParent();
}
});
此变体不应用于实际的类修改。
扩展现有的类以应用其他行为&渲染。使用此变体创建一个行为不同的子类型,而不会丢失原始类型。
在下面的示例中,我们使用一种方法扩展textfield,以便在设置名为setColored
的新值时更改labelcolor,并覆盖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
覆盖每个实例会在极少数情况下发生,并且可能不适用于所有属性。在这种情况下(我手边没有示例),您只需要一个不同的行为,您可以考虑覆盖每个实例的设置。基本上,当您在类创建上应用配置时,您始终会执行此类操作,但大多数时候您只是覆盖配置属性的默认值,但您也可以覆盖引用函数的属性。这完全覆盖了实现,您可能允许无权访问basetype(如果存在),这意味着您无法使用callParent
。您可以尝试使用setValue
来查看它无法应用于现有链。但同样,你可能会面临一些罕见的情况,这种情况很有用,即使它只是在开发过程中并重新实现以提高效率。对于这种情况,您应该在使用Ext.override创建特定内容后应用覆盖,如上所述。
重要提示:如果您不使用Ext.override,则无法通过调用
this
来访问该类实例!
如果我遗漏某些内容或某些内容(不再)正确,请发表评论或随时进行修改。
由 @Eric
评论这些方法都不允许您覆盖mixins(例如Ext.form.field.Field)。由于在定义类时将mixin函数复制到类中,因此必须直接将覆盖应用于目标类
答案 1 :(得分:1)
@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项目包含一个覆盖文件夹,只需将该文件添加到该文件夹即可确保应用覆盖。
答案 2 :(得分:0)
这是 ExtJS 7 中唯一对我有用的方法。
示例:
app/desktop/overrides/Toast.js
Ext.define(null, {
override: 'Ext.window.Toast',
show : function () {
this.callParent();
// Your custom code here...
}
});