code4jhon
code4jhon

Reputation: 6034

How to use Ext.ComponentQuery.query with nested attributes

How to use Ext.ComponentQuery.query with nested attributes in Sencha Touch?

e.g

var myHardtoGetObj = topLevelView.down('someview[config.categoryCfg.id=1]')[0];

This gets me "uncaught error"

given :

Ext.define('SomeView', {
    xtype : 'someview',
    config : {
        categoryCfg : {
            id   : 5,
            name : 'someName' 
        }
    }
});

Is this possible?

Thanks.

Upvotes: 0

Views: 5828

Answers (3)

Alex Tokarev
Alex Tokarev

Reputation: 4861

The canonical way of doing things like that is adding a custom pseudo class matcher:

Ext.ComponentQuery.pseudos.hasCategoryId = function(components, selector) {
    var result = [],
        c, i, len;

    for (i = 0, len = components.length; i < len; i++) {
        c = components[i];

        if (c.config.categoryCfg && c.config.categoryCfg.id == selector) {
            result.push(c);
        }
    }

    return result;
}

Then you can use this pseudo class both globally with Ext.ComponentQuery.query, and locally with methods like query, down, etc.:

var allMatched, someComponent;

allMatched = Ext.ComponentQuery.query(':hasCategoryId(1)');
someComponent = myPanel.down(':hasCategoryId(42)');

See more ways to skin the cat in ComponentQuery doc.

Upvotes: 2

todinov
todinov

Reputation: 504

This really is an interesting question. There doesn't seem to be an absolutely straightforward solution, however there is a rather quick workaround. You can modify your view code to:

Ext.define('SomeView', {
   xtype : 'someview',
   config : {
       categoryCfg : {
           id   : 5,
           name : 'someName' 
       }
   },

   hasCategoryId: function (id) {
       return this.getCategoryCfg().id == id;
   }
});

Then you can make a query like this:

Ext.ComponentQuery.query('someview{hasCategoryId(1)}');

or

topLevelView.down('someview{hasCategoryId(1)}');

Note: The syntax of the selector is xtype{memberMethod()} without a space in between. This way both selectors must match (the same way as .class1.class2 in CSS). Also the selectors must be in this order, because the result set is filtered by each selector in order and if some of the components don't have the hasCategoryId method it will break with just '{hasCategoryId(1)}'

Upvotes: 2

Although not exactly answering the question but you can do a little work around to get it to work.

you can add update method to your nestedConfig like so

Ext.define('myCoolClass', {
    config : {
        nestedConfig : {
            nestedId : 5
        },

        nestedId : null
    },

    updateNestedConfig: function (nestedConfig) {
        if (nestedConfig.nestedId) {
            this.setNestedId(nestedConfig.nestedId);
        }
    }
});

By doing that you now have access to normal component query attribute

Ext.ComponentQuery.query('[nestedId=555]')

As an example. If you take a look at Sencha source code they use this quite a lot like in NavigationView and TabPanels

Upvotes: 1

Related Questions