1. 程式人生 > >[老貼重發]EXT:指定樹控制元件TreePanel 展開到第幾層

[老貼重發]EXT:指定樹控制元件TreePanel 展開到第幾層

12年寫的文章了,可能由於某年帳號洩露,被人刪除了很多文章。

還有底搞的,我就重發一下。

對於Ext.tree.TreePanel,相信使用過EXT的人一般都用到過。所以本文中不會包含EXT或TreePanel 基礎知識的介紹了

     比如做一個行政區劃的樹。如下圖所示:

   

    但在有的時候,這顆樹的資料量會很大,層級也會很深,預設全部展開的話,會很慢,而且顯示一大堆東西出來,顯示不符合使用者的需求。可又不是預設全部摺疊,這樣使用者又第一眼看不見想關心的東西的內容。

    所以筆者在這裡提出了一個解決方案:展開到指定層級

    如上圖所示,在筆者剛剛完成的一個專案中,使用者只需要關心鄉鎮的資訊,偶爾會檢視一下鄉鎮下面的村組資訊。所以在這次應用中,需要預設把樹展開到鄉鎮一級。

    要達到以上目的呢,目前有兩種手段:

      1)通過非同步得到的節點資料資訊中,將需要展開的節點加屬性定義:expanded:true

           如一個json格式的節點: {id:"XXXX",text:"YYYY",expanded:true}

           這種方式需要編寫非同步取資料程式碼時,根據你要展開到的層級,計算哪些節點需要做設定:expanded:true

      2)利用Treepanel的load事件,定義其響應函式,在響應函式中新增控制邏輯。

     因為第一種方式,太過繁瑣,不適合封裝成專案級的控制元件,所以本文將重點介紹第二種方式。

  先來晒晒load事件的響應函式中的部分程式碼:[load事件:在節點載入後觸發。Fires when a node is loaded]

    在下面的程式碼中,除了實現了可以展開到指定層數,還可以只展開第一個節點及該節點之下的各層子節點

[javascript] view plain copy
  1. var level=2;//通過這裡指定展開到第幾層
  2.        if(level==0)//此時規定:只展開第一個節點及其所有子節點
  3. {    
  4.        Ext.each(node.childNodes, function(n){     
  5.         if(n.isFirst())  
  6.         {  
  7.         if(!n.isLeaf())          
  8.         {  
  9.                if(!n.isLoaded())  
  10.                {          
  11.               n.reload();  
  12.            }  
  13.         }  
  14.          }  
  15.      });  
  16. }  
  17.        if(level>0)//此時規定:根據設定的層數,展開到第level層
  18.        {  
  19.         var path=node.getPath();  
  20.         var index=path.indexOf('/');  
  21.         var loadedlevel=0;  
  22.         while(index>=0)   
  23.         {  
  24.             loadedlevel++;  
  25.             index=path.indexOf('/',index+1);          
  26.         }  
  27.         if(loadedlevel<level)  
  28.         {  
  29.             Ext.each(node.childNodes, function(n){    
  30.               if(!n.isLeaf()) //zhangpf 當n.isLeaf()=true時,n為Ext.tree.TreeNode型別,不具有isLoaded()和reload()方法       
  31.           {  
  32.                 if(!n.isLoaded())  
  33.                 {         
  34.                     n.reload();  
  35.                 }  
  36.               }  
  37.            });  
  38.         }  
  39.        }  

    程式碼不難,這裡就不多做詳解。這裡只說一點:關於isLoaded()和reload()方法,它們不是TreeNode的方法,而是屬於AsyncTreeNode的方法。所以在用它們時,要格外小心。

     OK,再晒下完整點的程式碼,它是我封裝的struts的頁面控制元件,最終生成的部分js。我又拿來修改些,去掉了些,所以不保證一定能執行起來。

    這裡補充一句:這裡的展開到指定層的邏輯,同樣適用於Ext改寫的ComboboxTree

[javascript] view plain copy
  1.  Ext.onReady(function(){  
  2.    var tree = new Ext.ux.ComboBoxTree({  
  3.         id:'XXXX',  
  4.         renderTo : 'XXX_div',  
  5.         hiddenName:"XXX_name",  
  6.         name: 'folderMoveTo',  
  7.         displayField: 'text',  
  8.                 valueField: 'id',  
  9.         width : 200,  
  10.         typeAhead: true,   
  11.             triggerAction: 'all',  
  12.             autoScroll : false,    
  13.             selectOnFocus: true,  
  14.                        forceSelection: true,  
  15.         tree : {  
  16.             xtype:'treepanel',  
  17.             listeners:{beforeload:loadTree,load:afterload},               
  18.              rootVisible: true,  
  19.              autoScroll : false,     
  20.                 autoHeight : true,    
  21.              root : new Ext.tree.AsyncTreeNode({id:'-1',text:'-請選擇-'})  
  22.         },  
  23.         selectNodeModel:'all'
  24.     });  
  25.     tree.setValue({id:'',text:'-請選擇-'});  
  26. });  
  27. function loadTree(node){  
  28.     if (node.id == "-1") {         
  29.             tree.tree.loader.dataUrl =  'http://127.0.0.1:9900/gmitp/platform/system/listAllArea.action?parentNodeId=-1';  
  30.     } else  {         
  31.         tree.tree.loader.dataUrl = 'http://127.0.0.1:9900/gmitp/platform/system/listAllArea.action?parentNodeId='+node.id;  
  32.     }  
  33. }     
  34. function afterload(node){  
  35.     //實現設定展開層數.
  36.        var level=3;  
  37.        if(level==0)//此時規定:只展開第一個節點及其所有子節點
  38.         {    
  39.             Ext.each(node.childNodes, function(n){    
  40.                 if(n.isFirst())  
  41.                 {  
  42.                     if(!n.isLeaf())          
  43.                     {  
  44.                         if(!n.isLoaded())  
  45.                         {         
  46.                             n.reload();  
  47.                         }  
  48.                     }  
  49.                     return;  
  50.                 }  
  51.              });  
  52.      }  
  53.        if(level>0)//此時規定:根據設定的層數,展開到第level層
  54.        {  
  55.         var path=node.getPath();  
  56.         var index=path.indexOf('/');  
  57.         var loadedlevel=0;  
  58.         while(index>=0)   
  59.         {  
  60.             loadedlevel++;  
  61.             index=path.indexOf('/',index+1);          
  62.         }  
  63.         if(loadedlevel<level)  
  64.         {  
  65.             Ext.each(node.childNodes, function(n){    
  66.                 if(!n.isLeaf()) //zhangpf 當n.isLeaf()=true時,n為Ext.tree.TreeNode型別,不具有isLoaded()和reload()方法       
  67.                 {  
  68.                     if(!n.isLoaded())  
  69.                     {         
  70.                         n.reload();  
  71.                     }  
  72.                 }  
  73.              });  
  74.         }  
  75.        }  
  76. }