午夜视频在线网站,日韩视频精品在线,中文字幕精品一区二区三区在线,在线播放精品,1024你懂我懂的旧版人,欧美日韩一级黄色片,一区二区三区在线观看视频

分享

ExtJS 2.2左邊導(dǎo)航菜單

 悟靜 2011-02-02
左邊導(dǎo)航菜單就是Asp.net中TabBox控件。在這里,我們也是形成一個組件的形式,看起來實現(xiàn)是有點復(fù)雜,但是如果建立在Ext的組件架構(gòu)基礎(chǔ)之上,就一點也不難了。Ext有一種布局叫做accordion。它是專門用來處理這種效果,它可以應(yīng)用在任何布局類中(如panel及其子類)。因為布局類中都會有著一些需要布局中的子組件。accordion布局的特性就是任何一個時候都只有一子組件處在激活狀態(tài),它的內(nèi)容處在展開狀態(tài),其它不處在激活狀態(tài)的子組件都會折疊其內(nèi)容。

如果布局類中的子組件都是面板的話(即Panel類),那么因為面板內(nèi)容的折疊/展開都是針對于其head標題部分。也就是說展開時,可以看到其內(nèi)容,沒有折疊時能看到其head標題部分,這就和我們TabBox特別相似了。

我們的TabBox是要在任何時刻都要顯示每個Tab子項的標題,而任何一個時刻都要顯示唯一的激活狀態(tài)的Tab子項的內(nèi)容。對于激活狀態(tài)的Tab子項的高度,它會占據(jù)其它Tab子項的所沒有占據(jù)的所有高度。這個accordion布局,在沒有指定子組件時,也會根據(jù)子組件來自動計算激活狀態(tài)子組件的高度以便占據(jù)整個剩余高度。

那么說來我們就可以采用Panel布局上加上accordion布局來模擬整個TabBox控件,而itmes中子Panel組件來用模擬Tab子項。組件就是類的形式,那么我們通過Panel來構(gòu)建這個LeftMenu類。為了使用這個leftMenu類擁有組件特性和Panel的功能,我們讓它來繼承于Panel類。那么如何使用LeftMenu類擁有Panel類的功能呢?第一是要繼承于Panel類,第二是在LeftMenu類把當(dāng)前的配置項都傳入到Panel類的構(gòu)建函數(shù)中去,同時改變它的作用域為當(dāng)前LeftMenu類的作用域,LeftMenu中的代碼:
Morik.Office.LeftMenu = function(config) {
Morik.Office.LeftMenu.superclass.constructor.call(this,config||{});①
    //實現(xiàn)本類的功能                                            ②
}
Ext.extend(Morik.Office.LeftMenu, Ext.Panel, {//加上LeftMenu類的方法});③

對于繼承,我們可以采用Ext.extend函數(shù),把Panel類中所有的方法都繼承到當(dāng)前類來,另外我們還可以通過第三個參數(shù)來實現(xiàn)本類的方法,這個與在構(gòu)建函數(shù)中通過this來實現(xiàn)方法有點不同,那就是其方法都定義在當(dāng)前類的prototype中。

在①處,我們通過Function類的call方法來改變Panel類的作用域為當(dāng)前類的作用域,同時把配置項也傳遞給Panel類。這就是為什么在該類中能使用父類中定義的配置項。在①處我們完全是傳入當(dāng)前類的配置項,這里應(yīng)該給了出一些默認值,而對于layout的配置項就不能通過當(dāng)前類傳入配置項來進行修改。看一下如何實現(xiàn)LeftMenu中的代碼:
var d = Ext.apply( {// default set
              split : true,
              region : 'west',
            width : 200,
              defaults : {
                  border : false
              }
,
              layoutConfig : {
                  animate : true
              }

           }, config || {});

    config = Ext.apply(d, {
       layout : 'accordion',
       collapsible : true
    }
);  
    Morik.Office.LeftMenu.superclass.constructor.call(this, config);

這段代碼替換代碼2.8中①處的代碼。它首先apply把傳入的配置項和默認是配置項組合起來,如果沒有傳入就采用默認的配置項。一般說來TabBox都會在左邊區(qū)域。其默認的寬度差不多也就是200px。每個Tab條目都不需要邊框。

接下就是不管是否傳入layout和collapsible的值為何值,都采用accordion布局和能折疊來進行配置。這兩個是TabBox的核心,不能修改。通過這些,我們就能通過panel父類來實現(xiàn)它的顯示出的樣子。

我們來運行下看看其效果。在看到其效果之后,我們得調(diào)用運行這個類,這個任務(wù)要在main.js中完成。即代碼2.7第三步中去進行完成。我們講到了LeftMenu的items子組一定要Panel。同時Panel中的內(nèi)容是樹形的條目(一般都是采用樹形結(jié)構(gòu),也可以不采用)。對應(yīng)圖2.5,我們先創(chuàng)建兩個子panel,這個兩個子Panel中items又含有一棵樹。Main.js中 的代碼:
var leftmenu = new Morik.Office.LeftMenu( {
           title : '我的辦公系統(tǒng)',
           items : [ {
              title : '我的辦公桌',
              items : [t1]
           }
, {
              title : '主數(shù)據(jù)管理',
              items : [t2]
           }
]      
});
 
這一段代碼取代原有l(wèi)eftmenu變量部分。兩個panel子組件都只要定義title,用來指定Tab項的標題,這個是一定要的,一是因為它的的提示作用,第二是因為如果沒有它,就不會有Tab條目了。那么不是TabBox了。items中只要包含一顆樹。兩個panel中分別包含是t1,t2兩棵樹。

那么我們得在代碼前面定義t1,t2兩個樹。定義樹一般都是通過TreePanel在實現(xiàn)樹的樣式及布局,樹的節(jié)點通過其樹的根節(jié)點一層層地串聯(lián)起來。我們可以采用每個節(jié)點都通過new TreeNode來創(chuàng)建,如何節(jié)點與節(jié)點之間有父子關(guān)系,那么就采用appendChild把子節(jié)點追加入父節(jié)點上,最后形成一條以根節(jié)點為首的節(jié)點鏈。把這個根節(jié)點通過TreePanel的root配置項傳到樹panel中。

這樣做會有很多冗余代碼。對于靜態(tài)的數(shù)據(jù)還會一種做法,就是通過AsyncTreeNode做為根節(jié)點的類型,之后就可以采用數(shù)組及Json對象的形式來動態(tài)構(gòu)建節(jié)點鏈。這個的用法在Ext的docs/resources/docs.js就是采用了它。我們看的文檔的左邊樹的節(jié)點數(shù)據(jù)就是這樣實現(xiàn)的。我們還是要看一下實現(xiàn)吧,Main.js中的代碼:
var t1 = new Ext.tree.TreePanel(  
    border : false,
    rootVisible : false,
    root : new Ext.tree.AsyncTreeNode( {
       text : "我的辦公桌",
       expanded : true,
       children : [ {id : "docRec",text : "接收公文",leaf : true },  
{id : "docSend",text : "發(fā)送公文",leaf : true},  
{id : "docManage",text : "公文管理",leaf : true}]
           }
)
       });
var t2 = new Ext.tree.TreePanel( {
    border : false,
    rootVisible : false,
    root : new Ext.tree.AsyncTreeNode( {
      text : "主數(shù)據(jù)管理",
      expanded : true,
      children : [
{id : "department",text : "部門管理",leaf : true},  
{id : "company",text : "公司管理",leaf : true},
{id : "permissions",text : "權(quán)限管理",
         children : [ {id : "permission",text : "權(quán)限管理",leaf : true},
{id : "permissionType",text : "權(quán)限類別",leaf : true}]
       }
]
    }
)
}
);

這兩棵樹的結(jié)構(gòu)差不多,先通過Ext.tree.TreePanel來生成一個樹面板。對于TabBox的樹面板,我們要取消其默認的邊框線。我們還看到兩個配置項,一個是root,一個是rootVisible,即然指定了root,又為什么要隱藏它呢。rootVisible設(shè)為false的話,那就是隱藏根節(jié)點本身,而根節(jié)點的子節(jié)點都不會隱藏的。很多時間根節(jié)點除了作一個串接所有子節(jié)點的作用,就沒有它的用途,所以就不要顯示出來,這里也是一樣。其根節(jié)點的提示作用就在上一部分的panel中title定義好了。

在根節(jié)點的配置項中,我們一定要指定expanded為true(也可以通過代碼來指定)。因為其默認是不展開,通過點擊根節(jié)點來展開其下層的子節(jié)點,而現(xiàn)在隱藏了,不能點擊,只能通過其expanded配置項來讓其下層的所有子節(jié)點都展開。

具體的數(shù)據(jù)其實都在children配置項給定了。對于每個節(jié)點,我們要一般來都要定義三項配置項:id,text,leaf/children。其中id是可以采用默認生成的。因為要用到它做為標識,我們就定義了。對于text,提示作用的。一定是要的。對于AsyncTreeNode的數(shù)據(jù),leaf和children一定要配置一個,leaf為true說明其為葉子節(jié)點,如果沒有就說明其不是葉子節(jié)點,那么就得到子節(jié)點,這個節(jié)點可能是多個,于是就得采用children來進行給定。

把這個加到main.js對應(yīng)的位置,運行一下,我們就可以看到圖2.5中左邊菜單的效果。對于上面的代碼,我們會覺得不應(yīng)該把TabBox中Tab項目來放在配置項中來配置,也就是每傳入一棵樹,就會有一個Tab項。它的標題就是樹不顯示出來的根節(jié)點文本,同時又為能使用items來配置那些可以其內(nèi)容不是樹的組件。我們可以另外實現(xiàn)一個配置,如tree,其要求就是把代碼2.10中items用trees:[t1,t2]來替換就能實現(xiàn)同樣的效果。

現(xiàn)在我們改進一個其leftMenu類。在代碼2.8的②后面加上如下:
for(var i=0;i<this.trees.length;i++)    
this.add({title:this.trees[i].getRootNode().text,
items:[this.trees[i]]}
);  

這段代碼就是根據(jù)有多少顆樹就在LeftMenu中的Items增加多少個Panel子組件。并指定子Panel的標題。加上這代碼,在使用它時,就可以不采用itmes,直接采用treees傳入tree就可以實現(xiàn)TabBox的效果。

實現(xiàn)完成上面,LeftMenu還沒有完成。它還有一個重大的任務(wù)就是實現(xiàn)一個點擊事件。實現(xiàn)事件可以分成如下三步,第一是在先注冊事件名,第二是在類的某一個時刻的代碼中運行這個事件函數(shù),(它是和事件名相對應(yīng)的回調(diào)函數(shù))。第三就是在注冊這個回調(diào)函數(shù)。這個注冊回調(diào)函數(shù)在main.js已經(jīng)完成。

根據(jù)上面的步驟,我們在leftMenu構(gòu)建函數(shù)中追加如下代碼:
this.addEvents('nodeClick');
this.initTreeEvent();
第一行是注冊事件名,第二行是通過一個類方法來實現(xiàn)運行這個事件函數(shù)。這個方法在代碼2.8中③處的第三個參數(shù)中的注釋后面加上它,下面我們就給出代碼2.8完整的LeftMenu中的代碼:
Ext.extend(Morik.Office.LeftMenu, Ext.Panel, {
    initTreeEvent : function() {
       if(!this.items) return;
       for (var i = 0;i < this.items.length; i++) {
         var p = this.items.itemAt(i);
         if (p)   var t = p.items.itemAt(0);
         if(t)  t.on( {
               'click' : function(node, event) {
                  if (node && node.isLeaf()) {
                     event.stopEvent();
                     this.fireEvent('nodeClick', node.attributes);}}

}
);
         }

       }

}
)

這段代碼的initTreeEvent是根據(jù)LeftMenu類items中子panel找到其中的樹組件,之后為每顆樹都注冊其click事件的回調(diào)函數(shù)。也就是每次點擊樹的時候(任何地方)它都會運行這個回調(diào)函數(shù)。在這個回調(diào)函數(shù)中,它進一步判斷,判斷點擊是否其樹的子節(jié)點。如果是的話,就停止事件的默認處理(冒泡給上一層,其缺省的動作),再運行我們在main.js中注冊的nodeClick的回調(diào)函數(shù)。

從運行的函數(shù)可以看出,這個回調(diào)函數(shù)參數(shù)只有一個,就是樹節(jié)點的屬性集合,它包括id,text,leaf等屬性。我們實現(xiàn)了LeftMenu的中樹的點擊事件,現(xiàn)在點擊樹葉子節(jié)點就會報錯,原因是我們還沒有實現(xiàn)MainPanel的loadTab方法。下一節(jié)中實現(xiàn)它。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多