Domanda

Tutta la documentazione e gli esempi ExtJS Ho letto suggeriscono chiamare i metodi della superclasse come questo:

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

Ho utilizzato questo modello per un bel po 'di tempo e il problema principale è che, quando si rinomina la classe allora si hanno anche per cambiare tutte le chiamate ai metodi della superclasse. Questo è abbastanza scomodo, spesso mi dimenticherò e poi devo rintracciare strani errori.

Ma leggendo la fonte di Ext.extend() ho scoperto, che invece ho potuto utilizzare i metodi superclass() o super() che Ext.extend() aggiunge al prototipo:

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

In questo codice rinominando MyPanel a qualcos'altro è semplice -. Non mi resta che cambiare l'una linea

Ma ho dei dubbi ...

  • Non ho visto questo documentato da nessuna parte e l'antica saggezza dice che non dovrei fare affidamento su un comportamento non documentato.

  • non ho trovato un solo uso di questi superclass() e supr() metodi nel codice sorgente ExtJS. Perché creare quando non si ha intenzione di usarli?

  • Forse questi metodi sono stati utilizzati in qualche versione precedente di ExtJS ma sono deprecati ora? Ma sembra una caratteristica così utile, perché si deprecare vero?

Quindi, dovrei utilizzare questi metodi o no?

È stato utile?

Soluzione

Sì, supr() non è documentato. Ho cercato l'ora di utilizzare in ExtJS 3.0.0 (un membro del personale Ext risposto nei forum, avevano aggiunto in questa versione), ma sembra orribilmente rotto.

Al momento non attraversa la gerarchia di ereditarietà, ma piuttosto salire di un livello, poi si blocca su questo livello, loop senza fine e fa esplodere la pila (IIRC). Quindi, se si hanno due o più supr() di fila, la vostra applicazione si romperà. Non ho trovato tutte le informazioni utili sul supr() nelle né i documenti né i forum.

Non so circa la release di manutenzione 3.0.x, dal momento che non ho avuto una licenza di supporto ...

Altri suggerimenti

Credo che questo è risolto in ExtJS 4 con 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]);
    }
});

Ecco un modello che uso, e intenzione di blog su di esso per un po '.

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

Ci sono un sacco di caratteristiche che si ottiene utilizzando questo modello, ma non c'è bisogno di utilizzare tutti loro

È possibile utilizzare questo poco conosciuto funzione 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 documentazione

Edit: In realtà, questo non è andare a lavorare con initComponent perché non è il costruttore. Ho sempre sovrascrivo il costruttore, personalmente (nonostante quello esempi Ext JS suggeriscono). Continuerà a pensare a questo un po '.

Vorrei semplicemente modificare il codice per:

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

In questo modo si mantiene solo un singolo riferimento del nome della classe, ora $ cls. Utilizzare solo $ cls con i tuoi metodi di classe e non avrete problemi.

Sono venuto con questa soluzione un paio d'ore fa 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;
}

Poi si può fare:

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

Testata solo con (Cromo 8.0.552.237 (70801) Ubuntu 10.10) e (Firefox 3.6.13).

Spero che questo aiuto a qualcuno, mi è stato quasi il passaggio a GWT.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top