彻底搞定 tree 菜单

tree菜单
placeholder image
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);

image.png

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这部分的东西了。

运行效果如图:

image.png

看到这个效果图,会感觉跟dtree或其他的没什么区别,呵呵,可别看小了这点。有学问的。

以上的例子,只为实现功能,部分代码写的不够合理,这里旨在实现。

这个控件实现的树,无限极的就不用说了,点击加载的时候有 loading...效果,其中有个问题,就是根节点的子节点,也就是第二级节点不好做,这里也实现了。

 点赞


 发表评论

当前回复:作者

 评论列表


留言区