Results 1 to 8 of 8

Thread: Ext.ComponentQuery - query by alternate alias fails

    Success! Looks like we've fixed this one. According to our records the fix was applied for EXTJS-3631 in a recent build.
  1. #1
    Sencha Premium User
    Join Date
    Nov 2010
    Location
    Chicago
    Posts
    2,339

    Default Ext.ComponentQuery - query by alternate alias fails

    Go here:

    http://dev.sencha.com/deploy/ext-4.0...rray-grid.html

    This query works:

    Ext.ComponentQuery.query("gridpanel")

    This query fails:

    Ext.ComponentQuery.query("grid")

    Both queries should return the same result since Ext.grid.Panel has two aliases.

    Code:
    Ext.define('Ext.grid.Panel', {
        extend: 'Ext.panel.Table',
        requires: ['Ext.grid.View'],
        alias: ['widget.gridpanel', 'widget.grid'],
    ....

  2. #2

    Default

    True. That's puzzling....

    Here's a fiddle with the bug:
    http://jsfiddle.net/Thinkscape/rNtHe/

  3. #3
    Ext JS Premium Member rex.staples's Avatar
    Join Date
    Jul 2007
    Location
    Austin, TX
    Posts
    35

    Default

    I found the same thing when wiring up the events for a combobox. The selector only works against the first item declared in a class definition ('combobox' works, 'combo' does not work)

    Code:
    alias: ['widget.component', 'widget.box']
    alias: ['widget.checkboxfield', 'widget.checkbox']
    alias: ['widget.combobox', 'widget.combo']
    alias: ['widget.filefield', 'widget.fileuploadfield']
    alias: ['widget.hiddenfield', 'widget.hidden']
    alias: ['widget.radiofield', 'widget.radio']
    alias: ['widget.textareafield', 'widget.textarea']
    alias: ['widget.triggerfield', 'widget.trigger']
    alias: ['widget.gridpanel', 'widget.grid']
    alias: ['widget.image', 'widget.imagecomponent']
    alias: ['widget.slider', 'widget.sliderfield']
    Here's why only the first alias gets applied (note the very last code comment):

    Code:
    Manager.registerPostprocessor('alias', function(name, cls, data) {
        var aliases = data.alias,
            widgetPrefix = 'widget.',
            i, ln, alias;
    
        if (!(aliases instanceof Array)) {
            aliases = [aliases];
        }
    
        for (i = 0, ln = aliases.length; i < ln; i++) {
            alias = aliases[i];
    
    
            this.setAlias(cls, alias);
        }
    
        // This is ugly, will change to make use of parseNamespace for alias later on
        for (i = 0, ln = aliases.length; i < ln; i++) {
            alias = aliases[i];
    
            if (alias.substring(0, widgetPrefix.length) === widgetPrefix) {
                // Only the first alias with 'widget.' prefix will be used for xtype
                cls.xtype = cls.$xtype = alias.substring(widgetPrefix.length);
                break;
            }
        }
    });
    The above is from ext-debug.js

  4. #4
    Ext JS Premium Member rex.staples's Avatar
    Join Date
    Jul 2007
    Location
    Austin, TX
    Posts
    35

    Default

    Here is a complete testbed which fixes the problem by overriding Ext.AbstractComponent.getXTypes(). This was the easiest way for me to deliver a fix in 1 piece.

    My first attempt at this solution modified the implementation of the function passed to Manager.registerPostprocessor('alias', <impl function>) in ext-debug.js ... I ended up using a different method that gets progressively faster as more and more base classes get their xtypes chain calculated.

    This solution below does not do anything to the registerPostprocessor <impl function> and instead focuses on adding alias support to the implementation of Ext.AbstractComponent.getXTypes() ... that said, the loop in ext-4.0.2/ext-debug.js ~ line 6644 could easily be modified and migrated into the (identical) loop above it.


    Code:
    <!DOCTYPE html>
    <html>
    <head>
    <title>Test</title>
    <script type="text/javascript" src="../ext-4.0.2/ext-debug.js"></script>
    <script type="text/javascript">
    
    Ext.define('Test.view.Viewport', {
        extend: 'Ext.container.Viewport',
        id: 'appwin',
        alias:  ['widget.vp1', 'widget.canvasviewport'],
        requires: ['Ext.form.field.TextArea'],
        items: { xtype: 'textareafield' }
    });
    
    Ext.define('Test.controller.Main', {
        extend: 'Ext.app.Controller',
        init: function() {
            this.control({
                'textarea': {
                    afterrender: function() { console.log('afterrender works!'); }
                }
            });
        }
    });
    
    Ext.onReady(function() {
    
        Ext.AbstractComponent.override({
          /**
           * This implementation of getXTypes recursively builds an ancestor
           * xtypes chain saving the chain at each level for faster subsequent
           * lookups (common base classes are only ever calculated 1 time).
           */
            getXTypes: function() {
                var self = this.self,
                    widgetPrefix = 'widget.',
                    parentPrototype = this.superclass,
                    xtypes, i, ln, alias, aliases, cls;
    
                if (self.xtypes === undefined) {
    
                    // fetch the ancestor xtypes chain
                    if (parentPrototype && (cls = Ext.getClass(parentPrototype))) {
                        if (cls.xtypes !== undefined) {
                            xtypes = cls.xtypes;
                            // parent xtypes has already been calculated
                        } else {
                            /* DEV NOTE:
                               This implementation reduces recursive calls by skipping
                               over superclass ancestors that do not have an xtype */
    
                            // continue up the chain until an object with an xtype is found
                            //   or until the end of the chain is reached
                            while (parentPrototype && cls && cls.xtype === undefined) {
                                if (parentPrototype = parentPrototype.superclass) {
                                    cls = Ext.getClass(parentPrototype);
                                }
                            }
    
                            // if the end of the chain was not reached, then recursively
                            //   calculate the parent xtypes
                            if (cls && cls.xtype !== undefined) {
                                xtypes = parentPrototype.getXTypes();
                            }
                        }
    
                        /* DEV NOTE:
                           This alternative implementation is simpler than the else
                           above at the cost of a few redundant recursive calls
                        */
                        //} else if (parentPrototype.getXTypes) {
                        //    xtypes = parentPrototype.getXTypes();
                        //}
                    }
    
                    // if the ancestor chain was populated seed it into the array for
                    //   calculating this class's xtypes
                    xtypes = xtypes ? [xtypes] : [];
    
                    // add to any ancestor xtypes chain by processing our aliases
                    aliases = Ext.ClassManager.getAliasesByName(this.$className);
    
                    // code borrowed from Ext 4.0.2 ext-debug.js ~ lines 6643 with this note:
                    // ---> This is ugly, will change to make use of parseNamespace...
                    for (i=0, ln = aliases.length; i < ln; i++) {
                        alias = aliases[i];
                        if (alias.substring(0, widgetPrefix.length) === widgetPrefix) {
                            xtypes.push(alias.substring(widgetPrefix.length));
                        }
                    }
    
                    self.xtypes = xtypes.join('/');
                    //console.log(this.$className,
                    //   '.getXTypes :: [', self.xtype, '] --> ', self.xtypes);
                }
    
                return self.xtypes;
            }
        });
    
    
    });
    
    Ext.application({
        autoCreateViewport: true,
        name: 'Test',
        controllers: ['Main'],
        launch: function() {
    
            var t = new Ext.form.field.TextArea();
            console.log('Ext.form.field.TextArea.getXTypes(): ', t.getXTypes());
    
            var q = new Ext.tip.QuickTip();
            console.log('Ext.tip.QuickTip.getXTypes(): ', q.getXTypes());
        }
    });
    
    
    </script>
    </head>
    <body></body>
    </html>

    I learned a ton about the class manager and saw some really interesting short-circuit techniques that I am going to adopt. I must say I absolutely love the modularized source -- it makes this kind of debugging exercise fun.

  5. #5
    Sencha User
    Join Date
    Mar 2011
    Location
    Germany
    Posts
    198

    Default

    REQUIRED INFORMATION Ext version tested:
    • Ext 4.0.2a
    • since preview

    Browser versions tested against:
    • FF4.0.1 (firebug 1.7.3 installed) Ubunutu 10.10
    • 12.0.742.91 (87961) Ubuntu 10.10

    Description:
    • Ext.ComponentQuery.query return empty array if queried by alternate alias
    • affects component.up()/.down()/.child()

    Steps to reproduce the problem:
    • Goto http://dev.sencha.com/deploy/ext-4.0...arch-grid.html
    • Use FireBug or Chrome Developer Tools
    • Run in the console:
    • 1. Ext.ComponentQuery.query('grid')
    • 2. Ext.ComponentQuery.query('gridpanel')
    • 3. Ext.ComponentQuery.query('gridpanel')[0].down('checkbox')
    • 4. Ext.ComponentQuery.query('gridpanel')[0].down('checkboxfield')
    • 5. Ext.ComponentQuery.query('checkboxfield').down('grid')
    • 6. Ext.ComponentQuery.query('checkboxfield').down('gridpanel')

    The result that was expected:
    • 1. array with 1 grid reference
    • 2. array with 1 grid reference
    • 3. reference to first checkbox field in the grid
    • 4. reference to first checkbox field in the grid
    • 5. reference to grid
    • 6. reference to grid

    The result that occurs instead:
    • 1. empty array
    • 2. array with 1 grid reference
    • 3. undefined
    • 4. reference to first checkbox field in the grid
    • 5. undefined
    • 6. reference to the grid instance

    Test Case: see above?!

    HELPFUL INFORMATION

    See this URL for live test case: http://dev.sencha.com/deploy/ext-4.0...arch-grid.html

    Debugging already done:

    • See Post #3


    Is affected the Components: ext-4.0.2a/src# find . -exec grep "alias: *\[.*,.*\]" '{}' \; -print
    alias: ['proxy.jsonp', 'proxy.scripttag'],
    ./data/proxy/JsonP.js
    alias: ['widget.image', 'widget.imagecomponent'],
    ./Img.js
    alias: ['layout.auto', 'layout.autocontainer'],
    ./layout/container/Auto.js
    alias: ['widget.component', 'widget.box'],
    ./Component.js
    alias: ['widget.combobox', 'widget.combo'],
    ./form/field/ComboBox.js
    alias: ['widget.hiddenfield', 'widget.hidden'],
    ./form/field/Hidden.js
    alias: ['widget.triggerfield', 'widget.trigger'],
    ./form/field/Trigger.js
    alias: ['widget.filefield', 'widget.fileuploadfield'],
    ./form/field/File.js
    alias: ['widget.textareafield', 'widget.textarea'],
    ./form/field/TextArea.js
    alias: ['widget.checkboxfield', 'widget.checkbox'],
    ./form/field/Checkbox.js
    alias: ['widget.radiofield', 'widget.radio'],
    ./form/field/Radio.js
    alias: ['widget.slider', 'widget.sliderfield'],
    ./slider/Single.js
    alias: ['widget.gridpanel', 'widget.grid'],
    ./grid/Panel.js

    Possible fix:
    • See Post #4

    Operating System:
    • Ubuntu 10.10




    Could not find any opend bug report and so used the bug template
    Last edited by Nickname; 29 Jun 2011 at 10:52 AM. Reason: Formatting

  6. #6
    Sencha User
    Join Date
    Mar 2011
    Location
    Germany
    Posts
    198

    Default

    4 weeks without reponse

    *push*

  7. #7
    Sencha User edspencer's Avatar
    Join Date
    Jan 2009
    Location
    Palo Alto, California
    Posts
    1,939

    Default

    Hey @nickname, sorry for the delayed response. This is now fixed locally and will be present in the next release
    Ext JS Senior Software Architect
    Personal Blog: http://edspencer.net
    Twitter: http://twitter.com/edspencer
    Github: http://github.com/edspencer

  8. #8
    Sencha User
    Join Date
    Mar 2011
    Location
    Germany
    Posts
    198

    Default

    Thank you very much for the update!

Posting Permissions

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