Pages

搜尋此網誌

2013年12月25日 星期三

extjs 如何使用 query component

extjs 如何使用 query component

使用 extjs 一定要會用它的 query component,使用起來有點類似 css selector,jquery 也是類似的概念,有些選擇語法意義是相同的,不管是在定義 controller,或是在 binding event 的時候都會用到他,筆者找到一篇中國朋友寫的 query component 介紹,藉由他的文章進行介紹,連結如下:ExtJs ComponentQuery

ID selector

根據元件 id 來 query,具有唯一性。前面以 # 號來代表, 取得 itemid 或者 id 符合的元件,範例如下:

var panel = Ext.ComponentQuery.query('#panel');

xtype selector

根據 xtype 來選擇,可選擇前面是否以 ‘.’ 來標示,或者沒有任何符號也代表 xtype 查詢,如:

var cmp= Ext.ComponentQuery.query('gridpanel');
var cmp= Ext.ComponentQuery.query('.gridpanel');

如果我們要找某個類型下面的所擁有的元件 ID 或 itemid,我們可以這樣下

panel#myPanel 

代表我要查詢 xtype 為 panel 底下有元件 id 為 myPanel

attributes selector

根據元件的屬性來選擇,舉例來說:

回傳擁有 iconCls 屬性的 Ext.Button 的實例:

var btnOk= Ext.ComponentQuery.query('button[iconCls]');

其中如果 iconCls 等於 null 或是 false 都視為不符合條件。

除此只外也可以判斷屬性指定特定的值,如下:

var btnOk= Ext.ComponentQuery.query('button[text = "ok"]'); 

取得 text 屬性為 ‘ok’ 的 Ext.Button 的。

值得注意的是,屬性可以是任何自定義屬性:

Ext.create("Ext.Panel" , {
   myAttribute: "helloWorld" 
});

Ext.ComponentQuery.query('panel[myAttribute= "helloWorld"]');

如上面的例子,自己定義的屬性也可以作為判斷。

descendant(後代) selector

用來選擇特定容器或容器組的後代,後代選擇器由兩個常用選擇器,中間加一個空格表示。其中前面的選擇器選擇父元件,後面的選擇器選擇後代元件,範例如下:

取得所有 id 為 ‘myCt’ 中的 Ext.Panel:

var panelsWithinmyCt = Ext.ComponentQuery.query('#myCt panel');

E F All descendant Components of E that match F (遞歸向下查詢所有可以符合的元件)

child selector

請注意這個選擇器與後代選擇器的區別,子選擇器(child selector)僅是指它的直接後代,而後代選擇器是作用於所有子後代元件。後代選擇器通過空格來進行選擇,而子選擇器是通過’>’進行選擇,範例如下:

取得所有 id 為 ‘myCt’ 的 container 中的直接子元件 Ext.Panel :

var directChildPanel = Ext.ComponentQuery.query(‘#myCt > panel’);

E > F All direct children Components of E that match F (查詢直接後代,其他非直接的則不符合)

參考下面範例來了解對應關係:

Ext.create("Ext.Panel" , {
    itemId: "myCt" ,
    itmes:[{
        xtype: "panel" ,
        html : "我是 myCt 的直接後代,也是 myCt 的後代" ,
        itmes: [{
            xtype: "panel" ,
            html : "我是 myCt 的後代,但不是直接後代" ,
        }]
    }]
});

parent selector

查找給定元素的父容器(遞迴向上查找所有符合的元素)。

E ^ F All parent Components of E that match F

Ext.ComponentQuery.query('textfield ^ form');

條件式關鍵字

~=:符合完整的字串,以空白字元分開,假設我們有兩個元件:

Ext.create('Ext.panel.Panel' , {
    cls: 'foo-cls my-cls bar-cls'
});

Ext.create( 'Ext.window.Window' , {
    cls: 'my-cls' 
});

下述查詢都會符合:

Ext.ComponentQuery.query('panel[cls~=my-cls]');

^=:開頭符合的屬性,如同 stratWith

$=:結尾符合的屬性,如同 endWith

*=:任何地方只要符合都算,如同 indexOf

@:只查詢使用類別的屬性,不會去查詢 extend 的父類別的屬性,使用方式:

Ext.ComponentQuery.query('panel[@collapsed=false]')

Conditional matching(條件符合)

符合同時滿足多個條件的符合表達式,AND:

Ext.ComponentQuery.query('panel[cls~=my-cls][floating=true][title$="sales data"]');

符合用 ‘,’ 逗號分隔的滿足任意一個條件的元件,OR:

Ext.ComponentQuery.query('field[fieldLabel^=User], field[fieldLabel*=password]');

Pseudo classes

查詢滿足條件的第一個元素,:first

Ext.ComponentQuery.query('panel > button:fi​​rst');

查詢滿足條件的最後一個元素,:last

Ext.ComponentQuery.query('form[title=Profile] field:last');

取得可以獲得焦點的元件,:focusable

panel . down ( ':focusable' ). focus ();

符合相反的結果,:not

取得所有field但是xtype不是hiddenfield的元件

form . query ( 'field:not( hiddenfield )' );

其中 hiddenfield 部分可以放任何表達式如 title^=hello

指定每間隔多少的元件,:nth-child

透過範例可以較清楚如何使用此種 selector

//找出奇數的元件
form.query('field:nth-child(2n+1)'); 
//也可以使用關鍵字 :nth-child(odd)

//找出偶數的元件
form.query('field:nth-child(2n)');
//也可以使用關鍵字:nth-child(even)

//找出 3 倍數的元件
form.query('field:nth-child(3n)');

關於使用 component.query 的效能上的建議

從 extjs component.query API 中,我們可以看到參數的使用為:query( selector, [root] )

其中 root 為選用,指的是要從哪個 Container 的範圍開始進行查詢,雖然是選用,強烈建議最好都要設置,如此一來在執行查詢時,extjs 在小範圍進行查詢,總比全域搜尋來的快,所以我們可以這樣執行:

var btnRefresh = Ext.ComponentQuery.query('#btnRefresh', container); 

使用 Ext.ComponentQuery 來進行查詢,又或者,我們可以直接對某個 container 進行 query

var btnRefresh = container.query('#btnRefresh');

效果跟第一種方式一樣,都是區域性的元件 query。

其他內建函數查詢

更精確的定義,可以參考官方的 API 說明,如每個函式的連結。

down([selector]):取得第一個的子元件

child([selector]):取得第一個直接子元件

up([selector],[limit]):取得最接近的 container。

搞懂 compnent query 可以讓你在 extjs 的世界事半工倍,而且一點也不難的。

張貼留言