ExtJS에서 슈퍼 클래스 방법을 호출하는 더 나은 방법
-
19-09-2019 - |
문제
내가 읽은 모든 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을 다른 것으로 바꾸는 것은 간단합니다. 한 줄만 변경해야합니다.
그러나 나는 의심이있다 ...
나는이 문서가 어디에서나 보지 못했고 오래된 지혜는 문서화되지 않은 행동에 의존해서는 안된다.
나는 이것들의 단일 사용을 찾지 못했습니다
superclass()
그리고supr()
extjs 소스 코드의 메소드. 당신이 그들을 사용하지 않을 때 왜 그것들을 만들까요?어쩌면 이러한 방법은 일부 이전 버전의 ExtJS에서 사용되었지만 현재 더 이상 사용되지 않았습니까? 그러나 그것은 유용한 기능인 것처럼 보입니다. 왜 당신은 그것을 감가 상각할까요?
그렇다면이 방법을 사용해야합니까?
해결책
네 확실합니다, supr()
문서화되지 않았습니다. 나는 ExtJS 3.0.0에서 그것을 사용하기를 고대하고있다 (EXT 직원이 포럼에서 대답했다. 그들은 그 버전에 그것을 추가했다).
현재 상속 계층 구조를 가로지 않고 오히려 한 레벨로 올라가서이 레벨에 갇히고 끝없이 고리를 뿌리고 스택 (IIRC)을 날려 버립니다. 따라서 두 개 이상이있는 경우 supr()
연속으로 앱이 깨질 것입니다. 유용한 정보를 찾지 못했습니다 supr()
문서 나 포럼에서.
지원 라이센스를받지 못했기 때문에 유지 보수 릴리스 3.0.x에 대해 잘 모르겠습니다.
다른 팁
나는 이것이 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]);
}
});
여기에 내가 사용하는 패턴이 있으며, 한동안 블로그에 대한 의미였습니다.
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);
이 패턴을 사용하는 기능이 많이 있지만 모두 사용할 필요는 없습니다.
이 작은 알려진 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);
}
});
보다 MDC 문서
편집 : 실제로, 이것은 생성자가 아니기 때문에 initcomponent와 함께 작동하지 않습니다. 나는 항상 생성자를 개인적으로 무시합니다 (Ext JS 예제에도 불구하고). 이것에 대해 계속 생각할 것입니다.
나는 단순히 당신의 코드를 다음으로 변경합니다.
var $cls = MyApp.MyPanel = Ext.extend(Ext.Panel, {
initComponent: function() {
// do something MyPanel specific here...
$cls.superclass.initComponent.call(this);
}
});
이렇게하면 클래스 이름의 단일 참조 만 $ CLS를 유지합니다. 클래스 방법 내에서만 $ CLS를 사용하면 괜찮을 것입니다.
나는 몇 시간 전에이 솔루션을 생각해 냈습니다.
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로 전환하고있었습니다.