实现原理:树的每一个节点都有自己的ID,和它的父亲节点的ID,还有自己的文本内容,以及点击后在哪个frame中打开哪个连接,是否是叶子节点等内容,树的第一级节点的父亲节点的ID我们将它置为0,以后每次点解一个非叶子节点的时候,我们都去异步加载他的所有孩子结点,将信息组装成JSON字符串,返回给前台,前台的EXT Tree使用JSON数据构造树
主要步骤:
第一步:构造 树的 表结构
- CREATE TABLE `ump_functions` (
- `item_id` int(11) NOT NULL,
- `item_name` varchar(60) DEFAULT NULL,
- `parent_id` int(11) DEFAULT NULL,
- `isleaf` tinyint(1) DEFAULT NULL,
- `Item_url` varchar(60) DEFAULT NULL,
- `remark` varchar(120) DEFAULT NULL,
- PRIMARY KEY (`item_id`)
- ) ENGINE=InnoDB DEFAULT CHARSET=gbk
CREATE TABLE `ump_functions` ( `item_id` int(11) NOT NULL, `item_name` varchar(60) DEFAULT NULL, `parent_id` int(11) DEFAULT NULL, `isleaf` tinyint(1) DEFAULT NULL, `Item_url` varchar(60) DEFAULT NULL, `remark` varchar(120) DEFAULT NULL, PRIMARY KEY (`item_id`) ) ENGINE=InnoDB DEFAULT CHARSET=gbk
第二步 构造和表关联的 javaBean对象 FuctionTreeNode.java
- package cn.com.xinli.tree.bean;
- /**
- *
- * @author huxl
- *
- * 代表系统左边的导航树的节点,根据节点的信息 异步动态加载 extTree
- * 根节点的 父节点的id是0
- */
- public class FuctionTreeNode
- {
- /*树节点id*/
- private int id;
- /*树节点名称*/
- private String text;
- /*树节点url*/
- private String href;
- /*点击叶子在指定的 frame中刷新*/
- private String hrefTarget="_blank";
- /*是否是叶子节点 */
- private boolean leaf;
- /*树节点的样式*/
- private String cls;
- public int getId()
- {
- return id;
- }
- public void setId(int id)
- {
- this.id = id;
- }
- public String getText()
- {
- return text;
- }
- public void setText(String text)
- {
- this.text = text;
- }
- public String getHref()
- {
- return href;
- }
- public void setHref(String href)
- {
- this.href = href;
- }
- public String getHrefTarget()
- {
- return hrefTarget;
- }
- public void setHrefTarget(String hrefTarget)
- {
- this.hrefTarget = hrefTarget;
- }
- public boolean isLeaf()
- {
- return leaf;
- }
- public void setLeaf(boolean leaf)
- {
- this.leaf = leaf;
- }
- public String getCls()
- {
- return cls;
- }
- public void setCls(String cls)
- {
- this.cls = cls;
- }
- }
package cn.com.xinli.tree.bean; /** * * @author huxl * * 代表系统左边的导航树的节点,根据节点的信息 异步动态加载 extTree * 根节点的 父节点的id是0 */ public class FuctionTreeNode { /*树节点id*/ private int id; /*树节点名称*/ private String text; /*树节点url*/ private String href; /*点击叶子在指定的 frame中刷新*/ private String hrefTarget="_blank"; /*是否是叶子节点 */ private boolean leaf; /*树节点的样式*/ private String cls; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getText() { return text; } public void setText(String text) { this.text = text; } public String getHref() { return href; } public void setHref(String href) { this.href = href; } public String getHrefTarget() { return hrefTarget; } public void setHrefTarget(String hrefTarget) { this.hrefTarget = hrefTarget; } public boolean isLeaf() { return leaf; } public void setLeaf(boolean leaf) { this.leaf = leaf; } public String getCls() { return cls; } public void setCls(String cls) { this.cls = cls; } }
第三步 根据节点id去找节点的孩子结点 FuctionTreeDaoImpl.java
- package cn.com.xinli.tree.dao.impl;
- import java.sql.Connection;
- import java.sql.PreparedStatement;
- import java.sql.ResultSet;
- import java.sql.SQLException;
- import java.util.ArrayList;
- import java.util.List;
- import org.apache.log4j.Logger;
- import cn.com.xinli.tree.dao.FuctionTreeDao;
- import cn.com.xinli.tree.bean.FuctionTreeNode;
- import cn.com.xinli.tree.util.DBUtil;
- public class FuctionTreeDaoImpl implements FuctionTreeDao
- {
- private Logger log=Logger.getLogger(FuctionTreeDaoImpl.class);
- public List<FuctionTreeNode> queryNodeById(String nodeId) throws Exception
- {
- Connection conn=null;
- PreparedStatement pstmt;
- ResultSet rs;
- List<FuctionTreeNode> nodeList=new ArrayList<FuctionTreeNode>();
- try {
- conn=DBUtil.getConnection();
- // String sql="select t.* from ump_functions t ,ump_role_function s where t.item_id = s.item_id and t.parent_id="+nodeId+" and s.role_id="+roleId ;
- String sql="select t.* from ump_functions t where t.parent_id="+nodeId;
- log.info("sql:"+sql);
- pstmt=conn.prepareStatement(sql);
- //pstmt.setInt(1, nodeId);
- rs=pstmt.executeQuery();
- while(rs.next())
- {
- FuctionTreeNode node=new FuctionTreeNode();
- node.setId(rs.getInt("item_id"));
- node.setText(rs.getString("item_name"));
- node.setLeaf(rs.getBoolean("isleaf"));
- node.setHref(rs.getString("item_url"));
- nodeList.add(node);
- }
- return nodeList;
- }
- catch (Exception e)
- {
- log.info("查询节点出错:", e);
- throw new Exception("查询节点出错");
- }
- finally
- {
- if(conn!=null)
- {
- try
- {
- conn.close();
- }
- catch (SQLException e)
- {
- log.info("数据库连接出错:", e);
- throw new Exception("数据库连接出错");
- }
- }
- }
- }
- }
package cn.com.xinli.tree.dao.impl; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import org.apache.log4j.Logger; import cn.com.xinli.tree.dao.FuctionTreeDao; import cn.com.xinli.tree.bean.FuctionTreeNode; import cn.com.xinli.tree.util.DBUtil; public class FuctionTreeDaoImpl implements FuctionTreeDao { private Logger log=Logger.getLogger(FuctionTreeDaoImpl.class); public List<FuctionTreeNode> queryNodeById(String nodeId) throws Exception { Connection conn=null; PreparedStatement pstmt; ResultSet rs; List<FuctionTreeNode> nodeList=new ArrayList<FuctionTreeNode>(); try { conn=DBUtil.getConnection(); // String sql="select t.* from ump_functions t ,ump_role_function s where t.item_id = s.item_id and t.parent_id="+nodeId+" and s.role_id="+roleId ; String sql="select t.* from ump_functions t where t.parent_id="+nodeId; log.info("sql:"+sql); pstmt=conn.prepareStatement(sql); //pstmt.setInt(1, nodeId); rs=pstmt.executeQuery(); while(rs.next()) { FuctionTreeNode node=new FuctionTreeNode(); node.setId(rs.getInt("item_id")); node.setText(rs.getString("item_name")); node.setLeaf(rs.getBoolean("isleaf")); node.setHref(rs.getString("item_url")); nodeList.add(node); } return nodeList; } catch (Exception e) { log.info("查询节点出错:", e); throw new Exception("查询节点出错"); } finally { if(conn!=null) { try { conn.close(); } catch (SQLException e) { log.info("数据库连接出错:", e); throw new Exception("数据库连接出错"); } } } } }
第4步: 写ext 的 tree 的js
- /*
- * Ext JS Library 2.0.1
- * Copyright(c) 2006-2008, Ext JS, LLC.
- * licensing@extjs.com
- *
- * http://extjs.com/license
- */
- Ext.onReady(function(){
- //从本地加载树的图片
- Ext.BLANK_IMAGE_URL = 'extjs/resources/images/vista/s.gif';
- var Tree = Ext.tree;
- var tree = new Tree.TreePanel({
- el:'tree-div',
- rootVisible:true, //隐藏根节点
- border:true, //边框
- animate:true, //动画效果
- autoScroll:true, //自动滚动
- enableDD:false, //拖拽节点
- containerScroll:true,
- loader: new Tree.TreeLoader({
- // dataUrl:'http://localhost:9090/struts2/menus.action'
- })
- });
- // set the root node
- var root = new Tree.AsyncTreeNode({
- text: '统一监控平台',
- draggable:false,
- //树的根节点的ID设置成0有个好处就是初始化树的时候默认先加载父亲节点为0的孩子结点
- id:'0'
- });
- tree.setRootNode(root);
- tree.on('beforeload',
- function(node)
- {
- tree.loader.dataUrl='http://localhost:9090/struts2/menus!loadTree.action?pid='+node.id
- //tree.loader.dataUrl='treedata2.txt'
- });
- // render the tree
- tree.render();
- root.expand();
- //展开树的所有节点,有一些特殊需求会要求我们一次展开所有的节点,传true
- //root.expand(true);
- //只展开根节点
- root.expand();
- });
/* * Ext JS Library 2.0.1 * Copyright(c) 2006-2008, Ext JS, LLC. * licensing@extjs.com * * http://extjs.com/license */ Ext.onReady(function(){ //从本地加载树的图片 Ext.BLANK_IMAGE_URL = 'extjs/resources/images/vista/s.gif'; var Tree = Ext.tree; var tree = new Tree.TreePanel({ el:'tree-div', rootVisible:true, //隐藏根节点 border:true, //边框 animate:true, //动画效果 autoScroll:true, //自动滚动 enableDD:false, //拖拽节点 containerScroll:true, loader: new Tree.TreeLoader({ // dataUrl:'http://localhost:9090/struts2/menus.action' }) }); // set the root node var root = new Tree.AsyncTreeNode({ text: '统一监控平台', draggable:false, //树的根节点的ID设置成0有个好处就是初始化树的时候默认先加载父亲节点为0的孩子结点 id:'0' }); tree.setRootNode(root); tree.on('beforeload', function(node) { tree.loader.dataUrl='http://localhost:9090/struts2/menus!loadTree.action?pid='+node.id //tree.loader.dataUrl='treedata2.txt' }); // render the tree tree.render(); root.expand(); //展开树的所有节点,有一些特殊需求会要求我们一次展开所有的节点,传true //root.expand(true); //只展开根节点 root.expand(); });
还有一个Ext 发送Ajax 请求的一个小例子 主要是使用到了 Ext.Ajax.request