【发布时间】:2012-12-24 15:04:05
【问题描述】:
我有一个Ext.form.field.Text,我想覆盖setValue 函数。
在 ExtJS 中覆盖此类功能的推荐方法是什么? Ext.override?
【问题讨论】:
-
我编辑了这个问题,使其更具建设性。请重新打开这个问题,因为答案对 ExtJs 社区非常有用。
标签: extjs extjs4 overriding extjs4.1
我有一个Ext.form.field.Text,我想覆盖setValue 函数。
在 ExtJS 中覆盖此类功能的推荐方法是什么? Ext.override?
【问题讨论】:
标签: extjs extjs4 overriding extjs4.1
为了澄清: 真正的类修改我的意思是一个预期的永久 类的修改/扩展,应始终通过扩展类来完成。 但这并不是仅针对特定问题(错误修复等)的临时解决方案。
您至少有四个选项来覆盖(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;
};
这是一个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(修复了c-p错误!感谢@nogridbag)
用例:我遇到了(我认为仍然存在的)不良行为 ExtJS 期望对象(键值对)正确的 radiogroup 值的设置。但我的后端只有一个整数。一世 首先使用 Ext.override 对
setValue()应用修复 方法,然后从无线电组扩展。在那里我只是做了一个 来自给定值的键值对并调用父方法 那个。
正如@rixo 提到的,这可用于覆盖实例成员。因此可能有资格覆盖甚至是 mixins(我自己从未测试过)
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 创建特定后应用覆盖。
重要提示:如果您不使用Ext.override,则无法通过调用
this访问类实例!
如果我遗漏了某些内容或某些内容(不再)正确,请发表评论或随时编辑。
正如 @Eric
评论的那样这些方法都不允许您覆盖 mixins(例如 Ext.form.field.Field)。由于 mixin 函数在您定义类时被复制到类中,因此您必须直接将覆盖应用到目标类
【讨论】:
Ext.form.field.Field)。由于 mixin 函数在您定义类时被复制到类中,因此您必须直接将覆盖应用到目标类。
override 这样的关键字,否则会出现错误。 ExtJS 不支持这个开箱即用。但是您可以为此添加自定义Ext.override,这仅适用于该方法不存在的情况。我只是不会将其命名为覆盖 ;) 另一种方法是在 callParent 调用之后的 initComponent 内。您现在可以检查方法是否存在,如果不存在则应用它。为此,您将使用Ext.applyIf。但是你永远不会知道同名的函数是否真的做同样的事情!
Ext.override——不仅是类——并让callParent在被覆盖的方法中工作(如函数文档中的示例所示) .
@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 中唯一适合我的方法。
例子:
app/desktop/overrides/Toast.js
Ext.define(null, {
override: 'Ext.window.Toast',
show : function () {
this.callParent();
// Your custom code here...
}
});
【讨论】: