更好的方法来调用父类方法ExtJS的
所有ExtJS的文档和例子我已阅读建议调用父类的方法是这样的:更好的方法来调用父类方法ExtJS的
MyApp.MyPanel = Ext.extend(Ext.Panel, {
initComponent: function() {
// do something MyPanel specific here...
MyApp.MyPanel.superclass.initComponent.call(this);
}
});
我一直在使用这种模式相当长的一段时间,主要的问题是,当你重命名你的类时,你也必须改变所有对超类方法的调用。这很不方便,我经常会忘记,然后我必须找出奇怪的错误。
但阅读的Ext.extend()
源,我发现,这不是我可以使用superclass()
或super()
方法是Ext.extend()
增加了原形:
MyApp.MyPanel = Ext.extend(Ext.Panel, {
initComponent: function() {
// do something MyPanel specific here...
this.superclass().initComponent.call(this);
}
});
在这段代码中重命名MyPanel别的东西很简单 - 我只是必须改变一条线。
但我怀疑...
我还没有看到这个记录任何地方和旧的观念认为,我不应该依靠无证行为。
我没有在ExtJS源代码中找到这些
superclass()
和supr()
方法的单个用法。为什么在你不使用它们时创建它们?也许这些方法在某些旧版本的ExtJS中使用,但现在不推荐使用?但它似乎是一个非常有用的功能,为什么你会弃用它?
那么,我应该使用这些方法吗?
是的,supr()
没有记录。我一直期待在ExtJS 3.0.0中使用它(一个Ext的工作人员在论坛中回复,他们已经在该版本中添加了它),但它似乎非常糟糕。
它目前没有遍历继承层次结构,而是上升一层,然后卡在这个层面上,无休止地循环并炸毁堆栈(IIRC)。所以,如果你连续有两个或更多的supr()
,你的应用会中断。我在文档和论坛上都没有找到关于supr()
的任何有用信息。
我不知道关于维护版本3.0.x的,因为我没有得到的支持许可证...
谢谢,它确实不适用于多层次的继承层次结构。供参考:3.0.3在这方面没有任何改变。 – 2009-11-13 08:47:42
仍然是Sencha Touch的案例1.1 – Vitaly 2011-05-06 13:48:33
你可以使用这个鲜为人知的Javascript功能(arguments.callee的):
MyApp.MyPanel = Ext.extend(Ext.Panel, {
constructor: function() {
// Do your thing
this.thing = 1;
// Call super
arguments.callee.superclass.constructor.apply(this, arguments);
}
});
编辑:其实,这是不会有initComponent的工作,因为它不是” t构造函数。我总是个人重写构造函数(尽管Ext JS示例提供了这些内容)。将继续考虑这一点。
下面是我用一个模式,一直想在博客了一会儿。
Ext.ns('MyApp.MyPanel');
MyApp.MyPanel = (function(){
var $this = Ext.extend(Ext.Panel, {
constructor: function() {
// Using a 'public static' value from $this
// (a reference to the constructor)
// and calling a 'private static' method
this.thing = $this.STATIC_PROP + privateStatic();
// Call super using $super that is defined after
// the call to Ext.extend
$super.constructor.apply(this, arguments);
},
initComponent: function() {
$super.initComponent.call(this);
this.addEvents([Events.SOMETHING]); // missing docs here
}
});
var $super = $this.superclass;
// This method can only be accessed from the class
// and has no access to 'this'
function privateStatic() {
return "Whatever";
}
/**
* This is a private non-static member
* It must be called like getThing.call(this);
*/
function getThing() {
return this.thing;
}
// You can create public static properties like this
// refer to Events directly from the inside
// but from the outside somebody could also use it as
// MyApp.MyPanel.Events.SOMETHING
var Events = $this.Events = {
SOMETHING: 'something'
}
return $this;
})();
MyApp.MyPanel.STATIC_STRING = 10;
//Later somewhere
var panel = new MyApp.Mypanel();
panel.on(MyApp.Mypanel.Events.SOMETHING, callback);
有很多的功能,你使用这种模式,但你不必使用所有这些
不错,但是这种方法引入了很多样板代码,如果调用大量的父类方法,这可能会很好,但我通常只需要调用initComponent()的父类和没有别的,在这种情况下额外的代码是恕我直言,不值得。 – 2010-11-02 13:24:29
是的,这种模式是所有的OO代码使用继承,你会调用父母的方法。在Ext中,我经常从父母处调用onRender,afterRender,beforeDestroy,因为我重写了它。 – 2010-12-23 18:49:16
这太好了,谢谢!我特别喜欢这个,因为如果正确完成,它可以通过JSLint/[JSHint](http://jshint.com/)。我有一些问题_linting_ [这是来自旧Sencha教程的格式](http://www.sencha.com/learn/legacy/Tutorial:Extending_Ext_for_Newbies#Extending_Functionality)。 – blong 2012-03-08 22:21:22
我会简单地改变你的代码:
var $cls = MyApp.MyPanel = Ext.extend(Ext.Panel, {
initComponent: function() {
// do something MyPanel specific here...
$cls.superclass.initComponent.call(this);
}
});
那方式你只保留一个你的类名称,现在$ cls的引用。只在你的类方法中使用$ cls,你会没事的。
如果我将每个类包装在闭包中,此解决方案将工作。目前我没有,所以这个解决方案不起作用。也许在某一天我会,所以这可以变得可行。 – 2011-01-10 16:28:54
我想出了这个解决方案在几个小时前heheh ...
function extend (parentObj, childObj) {
parentObj = parentObj || function() {};
var newObj = function() {
if (typeof this.initialize == 'function') {
this.initialize.apply(this, arguments);
}
}
newObj.prototype.__proto__ = parentObj.prototype;
for (var property in childObj) {
newObj.prototype[property] = childObj[property];
}
newObj.prototype.superclass = function (method) {
var callerMethod = arguments.callee.caller,
currentProto = this.constructor.prototype.__proto__;
while (callerMethod == currentProto[method]) {
currentProto = currentProto.__proto__;
}
return currentProto[method];
};
return newObj;
}
然后,你可以这样做:
var A = function() {
this.name = "A Function!";
};
A.prototype.initialize = function() {
alert(this.name);
}
var B = extend(A, {
initialize: function() {
this.name = "B Function!";
this.superclass('initialize').apply(this);
}
});
var C = extend(B, {
initialize: function() {
this.superclass('initialize').apply(this);
}
});
测试只(铬8.0.552.237(70801) Ubuntu 10.10) 和(Firefox 3.6.13)。
希望这有助于某人,我几乎切换到GWT。
'Function.caller'和'Object .__ proto__'都是非标准的。此外,后者已被弃用。虽然,这个想法看起来很有趣。 – 2011-01-26 22:13:16
我认为这是用callParent在ExtJS 4中解决的。
Ext.define('My.own.A', {
constructor: function(test) {
alert(test);
}
});
Ext.define('My.own.B', {
extend: 'My.own.A',
constructor: function(test) {
alert(test);
this.callParent([test + 1]);
}
});
+1正是我在找的:) – jrharshath 2011-09-01 07:14:52
这个问题涉及到Ext JS 3.x(对于稍后可能会阅读的用户) – blong 2013-01-23 23:03:25
其实,你可以试试'this.constructor.superclass.initComponent.call(this);'? – neonski 2009-11-12 21:24:04
谢谢,但这与Jabe描述的问题相同 - 它只适用于一个层次的层次结构。 – 2009-11-13 08:44:53