利用Dojo和JSON建立无限级AJAX动态加载的功能模块树

本文介绍如何使用Dojo实现动态加载的树形菜单功能,通过具体实例展示了前后端交互细节,并提供了一个完整的DEMO供读者参考。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        在JavaEye看了“使用hibernate实现树形结构无限级分类”这篇文章后,我也想将自己在所有开发的项目中使用的功能模块树的实现方法以及完整DEMO(含源码)贴出来和大家分享。其实在我的博客里是老早贴出来的,由于时间关系没好好整理。

       功能模块树是几乎在每个项目里都要用到的东西,利用Dojo的好处就是可以实现树的子节点的动态加载,这在树节点很多的情况下是很有用的。

        下载DEMO附件请到JavaEye: http://boogie.javaeye.com/blog/26240

        下载附件二dojotree.rar,解压后将dist/dojotree.war部署到应用服务器即可浏览DEMO,DEMO中内置HSQLDB数据库,启动时自动加载。DEMO运行截图见附件一。

一、tree.jsp主要代码

1、首先在head中导入Dojo库(dojo.js)和TreeWidget

< script type = " text/javascript "  src = " ajax/dojo/dojo.js " ></ script >
< script type = " text/javascript " >
dojo.require(
" dojo.widget.Tree " );
dojo.require(
" dojo.widget.TreeNode " );
dojo.require(
" dojo.widget.TreeSelector " );
dojo.require(
" dojo.widget.TreeRPCController " );
dojo.require(
" dojo.widget.TreeLoadingController " );
dojo.require(
" dojo.widget.TreeContextMenu " );
</ script >

2、在body中放置TreeWidget,TreeLoadingController中的RPCUrl="treeServlet"为从后台获取数据的servlet名称,TreeNode中的expandLevel表示树初始张开级别

  <div dojoType="TreeLoadingController" RPCUrl="treeServlet" widgetId="treeController" DNDController="create"></div>
  <div dojoType="TreeSelector" widgetId="treeSelector"></div>
  <div dojoType="Tree" DNDMode="between" selector="treeSelector" widgetId="bandTree" controller="treeController">
  <div dojoType="TreeNode" title="root" widgetId="root" objectId="root" isFolder="true" childIconSrc="images/comm.gif" expandLevel="1"/>

3、建立TreeSelector事件处理函数

function  treeSelectFired()  {
    
// get a reference to the treeSelector and get the selected node 
    var treeSelector = dojo.widget.manager.getWidgetById('treeSelector');
    
var treeNode = treeSelector.selectedNode;
    
// get a reference to the songDisplay div
    var hostDiv = document.getElementById("songDisplay");
    
var isFolder = treeNode['isFolder'];
    
//alert(isFolder);
    if ( !isFolder) {
       
var song = treeNode['title'];
       
var url = treeNode['url'];
       link(url);
    }
 else 
    }

}

4、将select事件处理函数关联到treeSelector

function  init() 

    
//get a reference to the treeSelector
    var treeSelector = dojo.widget.manager.getWidgetById('treeSelector');

    
//connect the select event to the function treeSelectFired()
    dojo.event.connect(treeSelector,'select','treeSelectFired'); 
}


dojo.addOnLoad(init);


二、主要java代码及数据结构

1、Gnmk.java中tree的属性

private  String id;    

private  String gnmkdm;   // 功能模块代码  

private  String gnmksm;   // 功能模块说明  
 
private  String gnmktb;   // 功能模块图标  

private  String gnmklj;   // 功能模块路径  

private  String gnmkmc;   // 功能模块名称  
  
private  String gnmksj;   // 功能模块上级代码  

private  String gnmkbz;   // 功能模块标志(‘N’为叶节点)  

2、HSQLDB内存数据库加载SQL(db.sql)

CREATE   TABLE  GNMK (ID  VARCHAR , GNMKDM  VARCHAR , GNMKMC  VARCHAR , GNMKLJ  VARCHAR , GNMKTB  VARCHAR , GNMKBZ  VARCHAR , GNMKSJ  VARCHAR );
INSERT   INTO  GNMK  VALUES  ( ' d098a59f0b765c30010b765d6b780001 ' ' 01 ' ' 一级目录1 ' null ' system.gif ' ' Y ' '' );
INSERT   INTO  GNMK  VALUES  ( ' d098a59f0b765e68010b765fda830001 ' ' 0101 ' ' 二级目录1 ' ' cxtjAction.do ' ' system.gif ' ' N ' ' 01 ' );
INSERT   INTO  GNMK  VALUES  ( ' d098a59f0b765e68010b765fda830001 ' ' 0102 ' ' 二级目录2 ' ' cxtjAction.do ' ' system.gif ' ' N ' ' 01 ' );
INSERT   INTO  GNMK  VALUES  ( ' d098a59f0b765c30010b765d6b780002 ' ' 02 ' ' 一级目录2 ' null ' system.gif ' ' Y ' '' );
INSERT   INTO  GNMK  VALUES  ( ' d098a59f0b765e68010b765fda830002 ' ' 0201 ' ' 二级目录1 ' ' cxtjAction.do ' ' system.gif ' ' N ' ' 02 ' );
INSERT   INTO  GNMK  VALUES  ( ' d098a59f0b765e68010b765fda830002 ' ' 0202 ' ' 二级目录2 ' ' cxtjAction.do ' ' system.gif ' ' Y ' ' 02 ' );
INSERT   INTO  GNMK  VALUES  ( ' d098a59f0b765e68010b765fda830002 ' ' 020201 ' ' 三级目录1 ' ' cxtjAction.do ' ' system.gif ' ' N ' ' 0202 ' );
INSERT   INTO  GNMK  VALUES  ( ' d098a59f0b765e68010b765fda830002 ' ' 020202 ' ' 三级目录2 ' ' cxtjAction.do ' ' system.gif ' ' N ' ' 0202 ' );

3、TreeServlet .java主要代码,在getGnmkByParent(String gnmksj)方法中可以实现自己的业务,DEMO中使用GnmkDAO

public   class  TreeServlet  extends  HttpServlet  {

    
private static final long serialVersionUID = 1L;

    
protected void doGet(HttpServletRequest request,
            HttpServletResponse response) 
throws ServletException, IOException {
        String action 
= request.getParameter("action");
        System.out.println(
"action b=>" + action);
        System.out.println(
"action b=>" + action);
        String data 
= request.getParameter("data");
        
if (action.equalsIgnoreCase("getChildren")) {
            JSONTokener jsonTokener 
= new JSONTokener(data);
            JSONObject jsonObject 
= (JSONObject) jsonTokener.nextValue();
            JSONObject parentNodeObject 
= (JSONObject) jsonObject.get("node");

            response.setContentType(
"text/json; charset=gb2312");
            PrintWriter out 
= response.getWriter();
            out.write(getChildren(parentNodeObject));
        }
 else {
        }

    }


    
private String getChildren(JSONObject parentNodeObject) {
        JSONArray result 
= new JSONArray();
        String parentObjectId 
= parentNodeObject.getString("objectId");// id 唯一
        
// String parentWidgetId = parentNodeObject.getString("widgetId");// dm
        parentObjectId = parentObjectId.equalsIgnoreCase("root"? ""
                : parentObjectId;
        System.out.println(
"parentObjectId=>" + parentObjectId);
        
// 获取子功能模块
        List listGnmk = this.getGnmkByParent(parentObjectId);
        System.out.println(
"listGnmk=>" + listGnmk.size());
        
if (listGnmk != null{
            Iterator itGnmk 
= listGnmk.iterator();
            
while (itGnmk.hasNext()) {
                Gnmk qxgnmk 
= (Gnmk) itGnmk.next();
                
try {
                    JSONObject jsonGnmkObject 
= new JSONObject();
                    String gnmkbz 
= qxgnmk.getGnmkbz();
                    
boolean isFolder = gnmkbz.equalsIgnoreCase("Y"? true
                            : 
false;
                    jsonGnmkObject.put(
"title", qxgnmk.getGnmkmc());
                    jsonGnmkObject.put(
"isFolder", isFolder);
                    jsonGnmkObject.put(
"widgetId", qxgnmk.getGnmkdm());
                    jsonGnmkObject.put(
"objectId", qxgnmk.getGnmkdm());
                    jsonGnmkObject.put(
"childIconSrc""images/"
                            
+ qxgnmk.getGnmktb());
                    jsonGnmkObject.put(
"url", qxgnmk.getGnmklj());
                    result.put(jsonGnmkObject);
                }
 catch (JSONException e) {
                    e.printStackTrace();
                }

            }

        }

        
return result.toString();
    }


    
private List getGnmkByParent(String gnmksj) {
        GnmkDAO gnmkDao 
= new GnmkDAO();
        
return gnmkDao.getGnmkByParent(gnmksj);
    }

}


三、关于DEMO的其它配置说明

1、实现javax.servlet.ServletContextListener接口的contextInitialized方法来加载HSQLDB及其数据, ContextListener.java主要代码

     public   void  contextInitialized(ServletContextEvent event)  {
        
try {
            
// load the driver
            Class.forName("org.hsqldb.jdbcDriver");
            
// create the table and add sample data
            InputStreamReader in = new InputStreamReader(getClass().getClassLoader().getResourceAsStream("db.sql"));
            BufferedReader reader 
= new BufferedReader(in);
            DBUtils.setupDatabase(reader);
        }
 catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        
    }

2、web.xml相关配置

     < listener >
        
< listener-class > dojo.sample.ContextListener </ listener-class >
    
</ listener >

    
< servlet >
        
< servlet-name > treeServlet </ servlet-name >
        
< servlet-class > dojo.sample.TreeServlet </ servlet-class >
    
</ servlet >
    
    
< servlet-mapping >
        
< servlet-name > treeServlet </ servlet-name >
        
< url-pattern > /treeServlet </ url-pattern >
    
</ servlet-mapping >
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值