程式扎記: [ 深入淺出 Ext 3.0 ] CH05 : 樹型結構

標籤

2011年12月7日 星期三

[ 深入淺出 Ext 3.0 ] CH05 : 樹型結構


前言 :
在應用程序中, 我們經常需要顯示或處理數狀結構的對像訊息, 比如部門組織與地區訊息等, 都是使用樹型結構不錯的範例. 對傳統 HTML 頁面來說, 完全靠手動編寫 js 來實現樹型結構不但困難且容易出錯. Ext 中提供了現成的樹控件, 通過這些控件可以在 B/S 應用中快速開發出包含樹行結構的應用.

簡單範例 :
樹控件由 Ext.tree.TreePanel 類定義. TreePanel 類繼承自 Panel 面板. 底下代碼簡單創建一棵樹並自動載開結點 :
- 01-02-01.html :
  1. Ext.onReady(function(){  
  2.   
  3.     var tree = new Ext.tree.TreePanel({  
  4.         el:'tree'  
  5.     });  
  6.   
  7.     var root = new Ext.tree.TreeNode({text:'我是根'});  
  8.     var node1 = new Ext.tree.TreeNode({text:'我是根的第一個分支'});  
  9.     var node2 = new Ext.tree.TreeNode({text:'我是根的第一個分支的第一個葉子'});  
  10.     var node3 = new Ext.tree.TreeNode({text:'我是根的第一個葉子'});  
  11.     node1.appendChild(node2);  
  12.     root.appendChild(node1);  
  13.     root.appendChild(node3);  
  14.   
  15.     tree.setRootNode(root);  
  16.     tree.render();  
  17.   
  18.     root.expand(truetrue);  
  19. });  

執行結果如下 :


使用 TreeLoader 獲取數據 :
自己編寫 JS 來產生樹型結構不僅麻煩, 而且容易出錯. 透過 Ext.tree.TreeLoader 可以利用後台獲取數據來動態生成樹型結構, 而我們只需要提供數據讓 TreeLoader 完成數據轉換和節點的操作. 在 TreeLoader 中我們透過提供 dataUrl 說明數據來源, 而 TreeLoader 會使用 Ajax 自動去獲取數據並進行解析 (數據來源為 JSon 格式.). 先來看一個簡單範例如下 :
- 01-04-02.txt : json 數據來源
  1. [  
  2.     {text:'01',children:[  
  3.         {text:'01-01',leaf:true},  
  4.         {text:'01-02',children:[  
  5.             {text:'01-02-01',leaf:true},  
  6.             {text:'01-02-02',leaf:true}  
  7.         ]},  
  8.         {text:'01-03',leaf:true}  
  9.     ]},  
  10.     {text:'02',leaf:true}  
  11. ]  

- 01-04-02.html :
  1. Ext.onReady(function(){  
  2.   
  3.     var tree = new Ext.tree.TreePanel({  
  4.         el: 'tree',  
  5.         loader: new Ext.tree.TreeLoader({dataUrl: '01-04-02.txt'})  
  6.     });  
  7.   
  8.     var root = new Ext.tree.AsyncTreeNode({text:'我是根'});  
  9.   
  10.     tree.setRootNode(root);  
  11.     tree.render();  
  12.   
  13.     root.expand();  
  14. });  

01-04-02.html 會讀取 01-04-02.txt 的內容來生成樹型結構, 執行結果如下 :


因為有時候樹型的數據並不多, 為了獲取如此少量數據而使用 Ajax 訪問後台實在不划算. 因此我們可以將 JSon 數據直接放在本地的 JS 來減少訪問後台的 cost. 參考範例如下 :
- 01-05-01.html :
  1. Ext.onReady(function(){  
  2.   
  3.     var tree = new Ext.tree.TreePanel({  
  4.         el: 'tree',  
  5.         loader: new Ext.tree.TreeLoader()  
  6.     });  
  7.   
  8.     // 將 JSon 數據放在 AsyncTreeNode 中.  
  9.     var root = new Ext.tree.AsyncTreeNode({  
  10.         text:'我是根',  
  11.         children: [  
  12.             {text: 'Leaf No. 1',leaf: true},  
  13.             {text: 'Leaf No. 2',leaf: true}  
  14.         ]  
  15.     });  
  16.   
  17.     tree.setRootNode(root);  
  18.     tree.render();  
  19.   
  20.     root.expand();  
  21. });  

執行結果如下 :


使用 JSP 提供後台數據 :
當樹型結構的數據過於龐大時, 我們可能希望只當節點被展開實, 才到後端要求數據, 以減少一次完全下載造成的時間延遲而影響到使用者經驗. 另外要注意的是使用此種方法需要給每一個 node 一個 id, 這樣後端才能知道是哪個 node 被展開以提供對應數據. 最後因為Ajax 默認使用 UTF-8編碼格式, 所以後端的 JSP 也要使用 UTF-8 編碼發送數據, 參考範例如下 :
- 01_07_02.jsp : 後台提供數據代碼
  1. <%@ page contentType="text/html;charset=utf-8"%>  
  2. <%  
  3.     request.setCharacterEncoding("UTF-8");  
  4.     response.setCharacterEncoding("UTF-8");  
  5.   
  6.     // 獲得node參數',對應的是正在展開的節點id  
  7.     String node = request.getParameter("node");  
  8.     System.out.println(node);  
  9.   
  10.   
  11.     String json = "";  
  12.     if ("0".equals(node)) {  
  13.         json += "[{id:1,text:'節點一'},{id:2,text:'節點二'}]";  
  14.     } else if ("1".equals(node)) {  
  15.         json += "[{id:11,text:'節點一的節點一',leaf:false},{id:12,text:'節點一的葉子一',leaf:true}]";  
  16.     } else if ("2".equals(node)) {  
  17.         json += "[{id:21,text:'節點二的葉子一',leaf:true},{id:22,text:'節點二的葉子二',leaf:true}]";  
  18.     } else if ("11".equals(node)) {  
  19.         json += "[{id:111,text:'節點一的節點一的葉子一',leaf:true},{id:112,text:'節點一的節點一的葉子二',leaf:true}]";  
  20.     }  
  21.   
  22.     response.getWriter().print(json);  
  23. %>  

- 01-07-01.html :
  1. Ext.onReady(function(){  
  2.   
  3.     var tree = new Ext.tree.TreePanel({  
  4.         el: 'tree',  
  5.         loader: new Ext.tree.TreeLoader({dataUrl: '01_07_02.jsp'})  
  6.     });  
  7.   
  8.     var root = new Ext.tree.AsyncTreeNode({  
  9.         id: '0'// 須提供 id 給後端 JSP 判斷展開的 Node 為何.  
  10.         text:'我是根'  
  11.     });  
  12.   
  13.     tree.setRootNode(root);  
  14.     tree.render();  
  15.   
  16.     root.expand(falsefalse);  
  17. });  

執行結果 :


變更節點的默認圖標 :
實際上每個樹型節點都有 icon 與 iconCls 屬性, 它們負責指定節點的圖標. 在修改節點的圖標時不論是透過 new 手工創建的節點還是通過 JSon 數據讀取到的節點, 它們的設置方式都是一樣的. 如果要使用 iconCls 時, 我們還需要在 HTML 中添加對應的 CSS 定義如下面代碼所示 :
- 設置 node 使用 iconCls :
  1. var node1 = new Ext.tree.TreeNode({  
  2.     text: 'iconCls',  
  3.     iconCls: 'icon-male' // 參考到 CSS 的 'icon-male'  
  4. });  

- 對應的 CSS 設置 :
  1. .x-tree-node-leaf .icon-male {  
  2.     background-image: url(user_male.png)  
  3. }  

這裡要注意的是 iconCls 對應的是 icon-male, 但寫在 CSS 裡要用層疊的寫法定義 .x-tree-node-leaf 下的 .icon-male, 否則 CSS 會不起作用. 另外如果同時設定 icon 與 iconCls 時, 因為 iconCls 是定義背景圖片, 所以 iconCls 的設定會被 icon 設置覆蓋過去. 範例代碼如下 :
- 04-01.html :
  1.           
  2.           

執行結果如下 :
This message was edited 14 times. Last update was at 08/09/2011 19:49:20

沒有留言:

張貼留言

網誌存檔

關於我自己

我的相片
Where there is a will, there is a way!