樹的控制項由 Ext.tree.TreePanel 類別定義, 控制項的名稱為 Treepanel. TreePanel 類別繼承自 Panel 面板. 在 Ext 中使用樹控制項非常簡單, 先參考簡單代碼如下:
- var tree = new Ext.tree.TreePanel({
- el: 'tree'
- });
- var root = new Ext.tree.TreeNode({text: 'Root'});
- tree.setRootNode(root);
- tree.render();
TreePanel 簡單範例:
上面已經建立一棵只有根的樹, 接下來我們要為樹加上枝與葉, 讓它看上去更像一棵樹. 參考代碼如下:
- var root = new Ext.tree.TreeNode({
- text:'Root'
- });
- var node1 = new Ext.tree.TreeNode({
- text: 'Node1'
- });
- var node2 = new Ext.tree.TreeNode({
- text: 'Leaf1'
- });
- var node3 = new Ext.tree.TreeNode({
- text: 'Leaf2'
- });
- node1.appendChild(node2);
- root.appendChild(node1);
- root.appendChild(node3);
預設樹是沒有展開的, 我們可以使用下面代碼讓樹預設是展開的:
- root.expand(true, true);
tree 的配置 與 使用 TreeLoader 取得資料:
我們也可以如下配置 TreePanel:
- var tree = new Ext.tree.TreePanel({
- renderTo:'tree',
- root: new Ext.tree.TreeNode({text: 'Root'})
- });
像上面那樣獲取資料不但麻煩而且容易出錯. 透過 Ext.tree.TreeLoader 可以利用從後台獲取資料組裝出一棵樹來, 而我們只要提供資料, 讓 TreeLoader 完成資料轉換和裝配節點的操作. 而這樣的動作自然又少不了 JSON 與 Ajax, 一旦涉及 Ajax 就需要配置伺服器. 首先我們需要為 TreePanel 設置一個 TreeLoader, 參考代碼如下:
- var tree = new Ext.tree.TreePanel({
- el:'tree',
- loader: new Ext.tree.TreeLoader({dataUrl: '1.txt'})
- });
- var root = new Ext.tree.AsyncTreeNode({text:'Root'});
- tree.setRootNode(root);
- tree.render();
- root.expand();
- [
- {text: 'not leaf'},
- {text: 'is leaf', leaf: true}
- ]
當你不斷點節 "+" 的節點時會發現數會無止盡的 expand 下去, 原因就在於 AsyncTreeNode 會繼承樹形 TreeLoader 中的 dataUrl. 當你展開節點時或執行對應節點的 expand() 方法時, 它會透過 Ajax 連結 dataUrl 指定的位址並會取資料, 而且還會把自己的 id 最為參數傳遞給 dataUrl 指定的位址. 而我們後台應該透過節點 id 計算出該返回的資料, TreeLoader 會根據獲得相應資料為樹形裝配節點, 並顯示到頁面上. 關鍵就在於我們使用 1.txt 提供的資料不會判斷當前的節點 id. 所以每次返回的資料都是一樣的, 也就是為什麼樹會無窮的展開下去的原因.
接著有著上面的了解, 我們提供一個較正常的 JSON 檔 2.txt 如下:
- 2.txt
- [
- {text:'01',children:[
- {text:'01-01',leaf:true},
- {text:'01-02',children:[
- {text:'01-02-01',leaf:true},
- {text:'01-02-02',leaf:true}
- ]},
- {text:'01-03',leaf:true}
- ]},
- {text:'02',leaf:true}
- ]
讀取本機 JSON 資料:
讀取本機 json 是 TreeLoader 的特殊使用方法. 因為有時候樹形資料並不多, 為了獲取少量資料而使用 Ajax 連結後台並不划算. 可是如果退到每個節點都使用 new 來生成又嫌麻煩. 那麼便可以使用下面方法讓 TreeLoader 讀取本機 JavaScript 中的 JSON 資料然後生成樹形節點. 首先為 TreePanel 設定一個參數為空的 TreeLoader, 然後設定根節點並為它設定 children 屬性放置 JSON:
- Ext.onReady(function(){
- var tree = new Ext.tree.TreePanel({
- el:'tree',
- loader: new Ext.tree.TreeLoader()
- });
- var root = new Ext.tree.AsyncTreeNode({
- text:'Root',
- children:[
- {text: 'Leaf No.1', leaf: true},
- {text: 'Leaf No.2', leaf: true}
- ]
- });
- tree.setRootNode(root);
- tree.render();
- root.expand();
- });
使用 JSP 提供後提資料:
之前範例使用 HTML 與 JavaScript 顯示樹形節點; 現在我們要把 TreeLoader 中的 dataUrl 改成我們現在用到的 tree.jsp, 修改後的代碼如下:
- var tree = new Ext.tree.TreePanel({
- el:'tree',
- loader: new Ext.tree.TreeLoader({dataUrl: 'tree.jsp'})
- });
- var root = new Ext.tree.AsyncTreeNode({
- text:'Root',
- id: '0'
- });
- tree.setRootNode(root);
- tree.render();
- root.expand();
- <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
- <%
- request.setCharacterEncoding("UTF-8");
- response.setCharacterEncoding("UTF-8");
- // obtain node id
- String node = request.getParameter("node");
- System.out.printf("Expand Node-%s...\n", node);
- String json = "";
- if("0".equals(node))
- {
- json+="[{id:1, text:'Node1'},{id:2, text:'Node2'}]";
- }
- else if("1".equals(node))
- {
- json+="[{id:11, text:'Node11'},{id:12, text:'Leaf12', leaf:true}]";
- }
- else if("2".equals(node))
- {
- json+="[{id:21, text:'Leaf21', leaf:true}]";
- }
- else if("11".equals(node))
- {
- json+="[{id:111, text:'Leaf111', leaf:true}]";
- }
- response.getWriter().print(json);
- %>
沒有留言:
張貼留言