我读过的所有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);
}
});
方法:
superclass()
在此代码中,将MyPanel重命名为其他内容很简单 - 我只需更改一行。
但我怀疑......
我没有在任何地方看到过这种情况,老智慧说,我不应该依赖无证行为。
我没有在ExtJS源代码中单独使用这些supr()
和{{1}}方法。为什么在你不打算使用它们时创建它们?
也许这些方法在某些旧版本的ExtJS中使用但现在已弃用了?但它似乎是一个非常有用的功能,你为什么要弃用呢?
那么,我应该使用这些方法吗?
答案 0 :(得分:29)
我认为这是使用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 :(得分:14)
确实,supr()
没有记录。我一直期待在ExtJS 3.0.0中使用它(一个Ext工作人员在论坛中回复,他们已经在该版本中添加了它),但它看起来非常糟糕。
它目前不会遍历继承层次结构,而是上升到一个级别,然后卡在这个级别上,无休止地循环并炸毁堆栈(IIRC)。因此,如果您连续两个或更多supr()
,您的应用就会中断。我在文档和论坛中都没有找到supr()
的任何有用信息。
我不知道维护版本3.0.x,因为我没有获得支持许可证......
答案 2 :(得分:5)
这是我使用的一种模式,并且有一段时间的博客意义。
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);
使用此模式可以获得许多功能,但您不必使用所有这些功能
答案 3 :(得分:3)
您可以使用这个鲜为人知的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,因为它不是构造函数。我总是个人覆盖构造函数(尽管Ext JS的例子建议)。将继续考虑这一点。
答案 4 :(得分:2)
我只想将您的代码更改为:
var $cls = MyApp.MyPanel = Ext.extend(Ext.Panel, {
initComponent: function() {
// do something MyPanel specific here...
$cls.superclass.initComponent.call(this);
}
});
这样你只保留一个类名的引用,现在是$ cls。只在你的班级方法中使用$ cls,你会没事的。
答案 5 :(得分:0)
我几个小时前想出了这个解决方案......呵呵......
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);
}
});
仅测试(Chromium 8.0.552.237(70801)Ubuntu 10.10) 和(Firefox 3.6.13)。
希望这对某人有所帮助,我几乎转向了GWT。