سؤال

تشير جميع وثائق OFTJS والأمثلة التي أقرأها إلى أساليب SuperClass مثل هذا:

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

لقد كنت أستخدم هذا النمط لبعض الوقت تماما والمشكلة الرئيسية، أنه عند إعادة تسمية فصلك، يجب عليك أيضا تغيير جميع المكالمات إلى طرق Superclass. هذا غير مريح للغاية، في كثير من الأحيان سوف أنسى ثم يجب علي تتبع الأخطاء الغريبة.

لكن قراءة مصدر 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 (أجاب موظف تحويلة في المنتديات، فقد أضافها في هذا الإصدار)، لكن يبدو أنه مكسور بشكل فظيع.

لا يجتاز حاليا التسلسل الهرمي للميراث، بل صعود مستوى واحد، ثم يتعطل على هذا المستوى، والحلقات التي لا نهاية لها وضرب المكدس (iirc). لذلك، إذا كان لديك اثنين أو أكثر supr() على التوالي، سيكون تطبيقك. لم أجد أي معلومات مفيدة supr() في لا المستندات ولا المنتديات.

لا أعرف عن إصدارات الصيانة 3.0.x، لأنني لم أحصل على ترخيص الدعم ...

نصائح أخرى

أعتقد أن هذا يتم حلها في extjs 4 مع 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]);
    }
});

إليك نمط أستخدمه، وكانت معنى للمدونة عن ذلك لفترة من الوقت.

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 المعروفة هذه (حجج.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.

تحرير: في الواقع، هذا لن يعمل مع InterComponent لأنه ليس المنشئ. أنا دائما تجاوز المنشئ، شخصيا (على الرغم من ما تشير أمثلة 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) أوبونتو 10.10) و (Firefox 3.6.13).

نأمل أن يساعد هذا شخص ما، كنت تبحث تقريبا إلى GWT.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top