How to use Ext.ComponentQuery in Ext JS 4
Hi, in this article I will show you how to use very important tool Ext.ComponentQuery. The Ext.ComponentQuery tool provides searching your components within Ext.ComponentManager, so you can find elements globally or you can search within a specific Ext.container.Container in your application.
How you can use it?
The syntax in this tool is similar to CSS selector, for example:
Ext.ComponentQuery.query(‘panel > form > textfield[name=login]‘).
I just showed you the most important function of Ext.ComponentQuery class. The query result will be in array. The Ext.ComponentQuery tool should return all the textfields that are in the form and matches the passed selector.
Let’s take a deeper look at the last query:
‘panel > form > textfield[name=login]‘
a) xtype – you can search by class alias, panel > form
b) class property, in this case, name – you can always match your class property to get the specific component
If you want you can also resolve it by itemId, which is alternative reference solution to your object instead of id and Ext.getCmp() method. Since itemId is index to the container’s internal MixedCollection, the itemId is scoped locally to the container. This solution supports duplicate conflicts in Ext.ComponentManager because id is always unique.
//when you work in the team, your id can be duplicated sometimes
The Ext.container.Container has functions: query, child, down and up.
//you can also use the Component itself to retrieve your item
Common ways to get object:
1. getComponent
parent.getComponent('itemId');
Returns the component of parent Container that matches the passed itemId, id or the position of the child component.
2. query
Ext.ComponentQuery.query('panel > form > button[itemId=save]')
or
parent.query('panel > form > button[itemId=save]')
Returns all components of the Container that matches the passed selector or empty array if no match was found. The second example returns all components only from parent.
3. child
parent.child('button[itemId=save]');
Returns the first direct child of the Container that matches the passed selector or null if no match was found.
4. down
parent.down('button[itemId=save]');
Returns the first descendant of the Container that matches the passed selector or null if no match was found.
5. up
component.up('panel[itemId=parent]');
Returns the ancestor of the Container that matches the passed selector or null if no match was found.
6. previousSibling or prev
component.previousSibling('panel[itemId=parent]');
or simply
component.previousSibling();
Returns the previous sibling of this Component or null if no match was found. The first line returns only previous panel with itemId = ‘parent’, so it will iterate items until find the valid panel. The second line returns any previous component.
7. nextSibling or next
component.nextSibling('panel[itemId=parent]');
or simply
component.nextSibling();
Returns the next sibling of this Component or null if no match was found. Behaviour is similar to previous example.
Bonus post!
Real world Example:
As always, I will use the application structure created here:
Creating fullscreen Ext JS 4 app with the BorderLayout
Of course you can use your own components. Ok, I will show you view file, the code look like below:
Ext.define('DevJS.view.Filter', { extend: 'Ext.form.Panel', xtype: 'filter-form', title: 'Filter', border: false, padding: 10, initComponent: function () { var me = this; this.items = [ { xtype: 'textfield', name: 'login', fieldLabel: 'By login', labelWidth: 50 }, { xtype: 'button', text: 'getLogin', name: 'filter', handler: function() { me.fireEvent('getLogin', me); } } ] //parent this.callParent(arguments); } });
The viewport changes in east region object:
{ title: 'East / Wschodni', region: 'east', margins: '0 5 0 5', width: 200, collapsible: true, collapsed: true, items: [ { title: '', xtype: 'filter-form' } ] }
The last change is located in the controller. The getLogin function demonstrate functionality of Ext.ComponentQuery. In this case the component object is a form passed by event handler.
Ext.define('DevJS.controller.Main', { extend: 'Ext.app.Controller', views:[ 'Filter' ], init: function () { var me = this; this.control({ 'filter-form': { 'getLogin': me.getLogin } }); }, getLogin: function(component){ console.log(component.down('textfield[name=login]').getValue()); } });
The result look like the following picture:
I searched for lsudol, somelogin values and the console log look like below:
Ok, next and last example will show you how to use down() and prev() functions. I modified getLogin body and look like the following code:
getLogin: function(component) { var button = component.down('button[name=filter]'); console.log(button.prev('textfield[name=login]').getValue()) }
And I searched for lsudol, login, test values again, the console log look like below:
When you create application in Ext JS 4 MVC architecture, it’s very important to use Ext.ComponentQuery because as you can see, it’s very helpful in development process. From your controller you can simply find and play with your application components. Have fun and see you soon.
Comments: