문제

내가 읽은 모든 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로 전환하고있었습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top