Question

Tous les documents ExtJS et des exemples que j'ai lu suggèrent d'appeler des méthodes superclasse comme ceci:

MyApp.MyPanel = Ext.extend(Ext.Panel, {
  initComponent: function() {
    // do something MyPanel specific here...
    MyApp.MyPanel.superclass.initComponent.call(this);
  }
});

J'utilise ce modèle pour un certain temps et le principal problème est que lorsque vous renommez votre classe, vous devez aussi changer tous les appels aux méthodes superclasse. C'est assez gênant, souvent je vais oublier et je dois traquer les erreurs étranges.

Mais la lecture de la source de Ext.extend() j'ai découvert qu'au lieu que je pouvais utiliser les méthodes de superclass() ou super() que Ext.extend() ajoute au prototype:

MyApp.MyPanel = Ext.extend(Ext.Panel, {
  initComponent: function() {
    // do something MyPanel specific here...
    this.superclass().initComponent.call(this);
  }
});

Dans ce code renommant MyPanel à quelque chose d'autre est simple -. Je dois juste changer une ligne

Mais je doute ...

  • Je ne l'ai pas vu cette documenté nulle part et la vieille sagesse dit, je ne devrais pas compter sur le comportement en situation irrégulière.

  • Je ne l'ai pas trouvé une seule utilisation de ces méthodes de superclass() et supr() dans le code source ExtJS. Pourquoi les créer quand vous n'allez les utiliser?

  • Peut-être que ces méthodes ont été utilisées dans une version plus ancienne de ExtJS mais sont maintenant dépréciée? Mais il semble une telle caractéristique utile, pourquoi vous désapprouver il?

Alors, dois-je utiliser ces méthodes ou non?

Était-ce utile?

La solution

Oui, en effet, supr() est pas documenté. J'ai hâte de l'utiliser dans ExtJS 3.0.0 (un membre du personnel Poste a répondu dans les forums, ils l'ont ajouté dans cette version), mais il semble horriblement brisée.

Actuellement, il ne traverse pas la hiérarchie d'héritage, mais plutôt de remonter d'un niveau, puis se coince à ce niveau, des boucles sans fin et souffle la pile (IIRC). Donc, si vous avez deux ou plusieurs supr() de suite, votre application se brisera. Je ne l'ai pas trouvé des informations utiles sur supr() dans ni les documents ni les forums.

Je ne sais pas sur les versions de maintenance 3.0.x, puisque je n'ai pas une licence de support ...

Autres conseils

Je pense que cela est résolu dans ExtJS 4 avec callParent.

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]);
    }
});

Voici un modèle que je l'utilise, et été un sens à un blog à ce sujet pendant un certain temps.

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);

Il y a beaucoup de fonctionnalités que vous obtenez en utilisant ce modèle, mais vous ne devez pas utiliser tous

Vous pouvez utiliser cette fonction peu connue 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);
    }
});

voir MDC documentation

Edit: En fait, cela ne va pas travailler avec InitComponent parce qu'il est pas le constructeur. J'ai toujours passer outre le constructeur, personnellement (malgré ce que des exemples Ext JS suggèrent). Continuera de penser à celui-ci un peu.

Je voudrais simplement changer votre code:

var $cls = MyApp.MyPanel = Ext.extend(Ext.Panel, {
  initComponent: function() {
    // do something MyPanel specific here...
    $cls.superclass.initComponent.call(this);
  }
});

De cette façon, vous conservez qu'une seule référence de votre nom de classe, maintenant $ cls. Utilisez uniquement $ cls au sein de vos méthodes de classe et vous serez très bien.

Je suis venu avec cette solution il y a deux heures hehe ...

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;
}

Ensuite, vous pouvez faire:

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);
    }
});

Testé uniquement avec (Chrome 8.0.552.237 (70801) Ubuntu 10.10) et (Firefox 3.6.13).

Hope this quelqu'un aide, je commutait presque GWT.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top