彻底搞定 tree 菜单
tree菜单admin 发布于:2010-10-12 18:33:00
阅读:loading
以前搞tree,接触的多的是 dtree,
dtree效果也还不错,一下子将所有的节点从底到高,一级一级的遍历,将基点一次性加载到客户端,由客户端来生成菜单,网上很多声音说不适合大型的应用,对这种方式的菜单不喜欢的也很多;
还有一种方式是点一下加载该级菜单的子级菜单,再点再加载,避免了一次性加载数量过大的原因,但,这种方式将数据保存在服务端,也就是说每次点击都会请求服务器,也会很浪费资源,
现在考虑的方式是,点击一个节点,加载这个节点下面的子级节点到客户端,再点就不会去重复加载了,只加载没有加载过的,即,将加载后的菜单保存到本地,这种方式,同时避免了dtree加载量大的问题,也避免了重复加载的问题,所以,还犹豫什么了,当然选择这个来作为我们的应用了,说到这里可能还不知道这个东西是啥,它叫“xloadtree”,是什么我就不再赘述,传说中CSDN的导航菜单也蛮不错的,感觉也是这种效果,是叫“梅花雪”的,什么的。
成功实现这样一个树菜单,我考虑的如下问题:
1、数据来源于数据库
2、解决常规性的问题
3、能够应用到系统中去
1、先说说数据库表结构
数据库名称为 :Struts ,新建表名称为 xloadtree,建表语句如下:
create table xloadtree(
xl_id int identity(1,1) primary key,--自增ID
xl_text varchar(50) default '',--节点名称
xl_action varchar(200) default '',--节点地址
xl_target varchar(50) default '',--提交方式
xl_fatherid int default -1--上级结点
)
go
--drop table xloadtree
select * from xloadtree
go
--添加根节点
insert into xloadtree(xl_text,xl_action,xl_target,xl_fatherid)
values('中国','javascript:void(0);','',-1);
--添加第一级子节点
insert into xloadtree(xl_text,xl_action,xl_target,xl_fatherid)
values('北京','http://www.beijing.com','framecdd',1);
insert into xloadtree(xl_text,xl_action,xl_target,xl_fatherid)
values('湖北','http://www.hubei.com','framecdd',1);
--添加第二级子节点
insert into xloadtree(xl_text,xl_action,xl_target,xl_fatherid)
values('海淀区','http://www.hdq.com','framecdd',2);
insert into xloadtree(xl_text,xl_action,xl_target,xl_fatherid)
values('朝阳区','http://www.cyq.com','framecdd',2);
insert into xloadtree(xl_text,xl_action,xl_target,xl_fatherid)
values('延庆区','http://www.yqq.com','framecdd',2);
insert into xloadtree(xl_text,xl_action,xl_target,xl_fatherid)
values('武汉市','http://www.wuhan.com','framecdd',3);
insert into xloadtree(xl_text,xl_action,xl_target,xl_fatherid)
values('襄樊市','http://www.xiangfan.com','framecdd',3);
insert into xloadtree(xl_text,xl_action,xl_target,xl_fatherid)
values('荆州市','http://www.jinzhou.com','framecdd',3);
--添加第4级子节点
insert into xloadtree(xl_text,xl_action,xl_target,xl_fatherid)
values('武昌','http://www.wuchangqu.com','framecdd',7);
insert into xloadtree(xl_text,xl_action,xl_target,xl_fatherid)
values('汉口','http://www.hankou.com','framecdd',7);
insert into xloadtree(xl_text,xl_action,xl_target,xl_fatherid)
values('老河口市','http://www.laohekou.com','framecdd',8);
insert into xloadtree(xl_text,xl_action,xl_target,xl_fatherid)
values('谷城县','http://www.laohekou.com','framecdd',8);
--第一级菜单
insert into xloadtree(xl_text,xl_action,xl_target,xl_fatherid)
values('上海','http://www.shanghai.com','framecdd',1);
2、面向这个tree的JavaBean对象,如下:
package com.db;
public class TreeBean {
private int xl_id = 0;
private String xl_title = "";
private String xl_action = "";
private String xl_target = "";
private int xl_fatherid = 0;
public int getXl_fatherid() {
return xl_fatherid;
}
public void setXl_fatherid(int xl_fatherid) {
this.xl_fatherid = xl_fatherid;
}
public int getXl_id() {
return xl_id;
}
public void setXl_id(int xl_id) {
this.xl_id = xl_id;
}
public String getXl_target() {
return xl_target;
}
public void setXl_target(String xl_target) {
this.xl_target = xl_target;
}
public String getXl_title() {
return xl_title;
}
public void setXl_title(String xl_title) {
this.xl_title = xl_title;
}
public String getXl_action() {
return xl_action;
}
public void setXl_action(String xl_action) {
this.xl_action = xl_action;
}
}
3、数据库现在给出的是2005的链接:
package com.db;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
public class DBManager {
private final static String DRIVER_NAME = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
private final static String URL = "jdbc:sqlserver://localhost:1433;databasename=Struts;";
private final static String USERNAME = "sa";
private final static String PASSWORD = "";
public static Connection getConnection() {
Connection conn = null;
try {
Class.forName(DRIVER_NAME);
conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
} catch (Exception e) {
System.out.println("打开数据库链接异常...");
e.printStackTrace();
}
return conn;
}
public static void Close(Connection conn) {
if (conn != null)
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
}
}
4、显示tree的页面代码为:
<%@ page language="java" pageEncoding="UTF-8"%>
<jsp:directive.page import="com.db.DBManager" />
<jsp:directive.page import="java.sql.Connection" />
<jsp:directive.page import="java.sql.PreparedStatement" />
<jsp:directive.page import="java.sql.ResultSet" />
<jsp:directive.page import="com.db.TreeBean" />
<jsp:directive.page import="java.util.ArrayList" />
<%
Connection conn = DBManager.getConnection();
String sql = "select top 1 * from xloadtree where xl_fatherid = -1 union all select * from xloadtree where xl_fatherid = 1";
PreparedStatement pst = conn.prepareStatement(sql);
ResultSet rs = pst.executeQuery();
ArrayList<TreeBean> arrayList = new ArrayList<TreeBean>();
while (rs!=null&&rs.next()) {
TreeBean bean = new TreeBean();
bean.setXl_id(rs.getInt(1));
bean.setXl_title(rs.getString(2));
bean.setXl_action(rs.getString(3));
bean.setXl_target(rs.getString(4));
bean.setXl_fatherid(rs.getInt(5));
arrayList.add(bean);
}
rs.close();
pst.close();
DBManager.Close(conn);
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>例子</title>
<script type="text/javascript" src="/xloadtree/xloadtree/xtree.js"></script>
<script type="text/javascript" src="/xloadtree/xloadtree/xmlextras.js"></script>
<script type="text/javascript" src="/xloadtree/xloadtree/xloadtree.js"></script>
<script type="text/javascript" src="/xloadtree/xloadtree/json_parse.js"></script>
<script type="text/javascript" src="/xloadtree/xloadtree/json2.js"></script>
<link rel="stylesheet" type="text/css"
href="/xloadtree/xloadtree/xtree.css" />
</head>
<body>
<%
TreeBean first = arrayList.get(0);
%>
<script type="text/javascript">
try{
var tree = new WebFXLoadTree("<%=first.getXl_title() %>","loadtree.jsp?xl_id=1");
<%
StringBuilder sb = new StringBuilder();
sb.append("[");
for(int i=1;i<arrayList.size();i++){
TreeBean bean = arrayList.get(i);
if(i==arrayList.size()){
sb.append("{\"text\":\"" + bean.getXl_title() + "\",\"action\":\"" + bean.getXl_action() + "\",\"target\":\"" + bean.getXl_target() + "\",\"src\":\"loadtree.jsp?xl_id=" + bean.getXl_id() + "\"}");
}else{
sb.append("{\"text\":\"" + bean.getXl_title() + "\",\"action\":\"" + bean.getXl_action() + "\",\"target\":\"" + bean.getXl_target() + "\",\"src\":\"loadtree.jsp?xl_id=" + bean.getXl_id() + "\"},");
}
%>
<%
}
sb.append("]");
%>
document.write(tree);
}catch(e){
alert(e.description);
}
</script>
<iframe frameborder="1" align="right" src="#" name="framecdd" id="framecdd" width="60%" height="60%"></iframe>
</body>
</html>
5、加载子级tree节点的页面代码为:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<jsp:directive.page import="java.sql.Connection" />
<jsp:directive.page import="com.db.DBManager" />
<jsp:directive.page import="java.sql.PreparedStatement" />
<jsp:directive.page import="java.sql.ResultSet" />
<%
String reqxl_id = request.getParameter("xl_id") == null ? "0"
: request.getParameter("xl_id");
Connection conn = DBManager.getConnection();
String sql = "select * from xloadtree where xl_fatherid = "
+ reqxl_id;
PreparedStatement pst = conn.prepareStatement(sql, 1005, 1007);
ResultSet rs = pst.executeQuery();
rs.last();
int counts = rs.getRow();
int num = 1;
StringBuilder sb = new StringBuilder();
sb.append("[");
rs.absolute(0);
while (rs != null && rs.next()) {
int id = rs.getInt(1);
String text = rs.getString(2);
String action = rs.getString(3);
String target = rs.getString(4);
int father = rs.getInt(5);
if (num == counts) {
sb.append("{\"text\":\"" + text + "\",\"action\":\""
+ action + "\",\"target\":\"" + target
+ "\",\"src\":\"loadtree.jsp?xl_id=" + id + "\"}");
} else {
sb.append("{\"text\":\"" + text + "\",\"action\":\""
+ action + "\",\"target\":\"" + target
+ "\",\"src\":\"loadtree.jsp?xl_id=" + id + "\"},");
}
num++;
}
sb.append("]");
rs.close();
pst.close();
conn.close();
out.println(sb.toString());
%>
就这么点点,当然了,除了这部分的东西,当然还需要xloadtree这部分的东西了。
运行效果如图:
看到这个效果图,会感觉跟dtree或其他的没什么区别,呵呵,可别看小了这点。有学问的。
以上的例子,只为实现功能,部分代码写的不够合理,这里旨在实现。
这个控件实现的树,无限极的就不用说了,点击加载的时候有 loading...效果,其中有个问题,就是根节点的子节点,也就是第二级节点不好做,这里也实现了。
点赞