Results 1 to 5 of 5

Thread: 3.4.1.1 Ext.define() breaks the xtype reference

    Thank you for reporting this bug. We will make it our priority to review this report.
  1. #1
    Sencha User SimoAmi's Avatar
    Join Date
    Oct 2008
    Location
    New York
    Posts
    119

    Default 3.4.1.1 Ext.define() breaks the xtype reference

    REQUIRED INFORMATION


    Ext version tested:
    • Ext 3.4.1.1
    Browser versions tested against:
    • Chrome 26
    • FF 20
    Description:
    • Ext.define() breaks the xtype reference. Instances of components extended through Ext.define() end up having the wrong constructor.
    Steps to reproduce the problem:
    • Define and extend an Ext component.
    • Specify an xtype.
    • Create an instance of the newly defined component.
    • Call getXType() on the new component instance.
    The result that was expected:
    • the returned xtype should reflect the one defined for the new component.
    The result that occurs instead:
    • the returned xtype does not reflect the one defined for the new component, but its parent.
    Test Case:

    Code:
    // Classic way
    Ext.ns('Test.CustomPanel');
    Test.CustomPanel = Ext.extend(Ext.Panel, {
      xtype: 'custompanel'
    });
    Ext.reg('custompanel', Test.CustomPanel);
    
    var c = Ext.create({ xtype: 'custompanel' });
    
    c.getXType()
    "custompanel"  // CORRECT
    
    
    c.getXTypes()
    "component/box/container/panel/custompanel"  // CORRECT
    Code:
    // With Ext.define()Ext.define('Test.CustomPanel', {
      extend: 'Ext.Panel',
      xtype: 'custompanel'
    });
    
    var c = Ext.create({ xtype: 'custompanel' });
    
    c.getXType()
    "panel"  // INCORRECT
    
    c.getXTypes()
    "component/box/container/panel"  // INCORRECT
    HELPFUL INFORMATION


    Debugging already done:
    • Instances of components extended through Ext.define() end up having the wrong constructor.
    Possible fix:
    • not provided
    Operating System:
    • MAC OSX

  2. #2
    Sencha User
    Join Date
    Jul 2009
    Posts
    4

    Default

    We use the following workaround for getXType()
    Code:
    Ext.override(Ext.Component, {
        getXType: function () {
            return (this.self || this.constructor).xtype;
        }
    });

  3. #3
    Sencha Premium User mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    40,449

    Default

    Thanks for the report! I have opened a bug in our bug tracker.

  4. #4
    Sencha User SimoAmi's Avatar
    Join Date
    Oct 2008
    Location
    New York
    Posts
    119

    Default

    Thanks for looking into it. Just to point out that impact is broad as there are multiple methods affected by this:

    - isXType()
    - getXType()
    - getXTypes()
    - findByType()
    - findParentByType()
    - other derivatives and dependencies of the above.
    Last edited by SimoAmi; 6 May 2013 at 8:17 AM. Reason: formatting

  5. #5
    Ext JS Premium Member
    Join Date
    Aug 2007
    Location
    Antwerp, Belgium
    Posts
    582

    Default

    This override should fix all issues with Ext.define (make it fully compatible with Ext.extend).

    Please those who are following this thread: test this and give me feedback. I have done some testing myself, and it seems to work, but this is some of the trickiest code in the entire ExtJS codebase and it is very difficult to reason about it.

    Code:
    // override 3.4.1.1 to fix Ext.define so it behaves the same as Ext.extend
    // Fixes http://www.sencha.com/forum/showthread.php?278660
    // Fixes http://www.sencha.com/forum/showthread.php?262945
    Ext.define = function (className, body, createdFn) {
       var override = body.override,
           cls, extend, name, namespace;
    
       if (override) {
           delete body.override;
           cls = Ext.getClassByName(override);
           Ext.override(cls, body);
       } else {
           if (className) {
               namespace = Ext.createNamespace(className, true);
               name = className.substring(className.lastIndexOf('.')+1);
           }
    
    // start of changes:
          
           extend = body.extend;
           if (extend) {
               delete body.extend;
               if (typeof extend == 'string') {
                   extend = Ext.getClassByName(extend);
               }
           } else {
               extend = Ext.Base;
           }
          
           var oc = Object.prototype.constructor;
           cls = (body.constructor != oc) ? body.constructor : null;
           if (!cls) {
              cls = function(){extend.apply(this, arguments);};
           }
          
    // end of changes
          
           if (className) {
               cls.displayName = className;
           }
           cls.$isClass = true;
           cls.callParent = Ext.Base.callParent;
    
           if (typeof body == 'function') {
               body = body(cls);
           }
    
           Ext.extend(cls, extend, body);
           if (cls.prototype.constructor === cls) {
    // start of changes:          
               //delete cls.prototype.constructor;
    // end of changes
           }
    
           // Not extending a class which derives from Base...
           if (!cls.prototype.$isClass) {
               Ext.applyIf(cls.prototype, Ext.Base.prototype);
           }
           cls.prototype.self = cls;
           
           if (body.xtype) {
               Ext.reg(body.xtype, cls);
           }
           cls = body.singleton ? new cls() : cls;
           if (className) {
               namespace[name] = cls;
           }
       }
    
       if (createdFn) {
           createdFn.call(cls);
       }
    
       return cls;
    };

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •