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

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

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

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

一、tree.jsp主要代码

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

  1. "text/javascript"src="ajax/dojo/dojo.js">
  2. "text/javascript" >
  3. dojo.require("dojo.widget.Tree");
  4. dojo.require("dojo.widget.TreeNode");
  5. dojo.require("dojo.widget.TreeSelector");
  6. dojo.require("dojo.widget.TreeRPCController");
  7. dojo.require("dojo.widget.TreeLoadingController");
  8. dojo.require("dojo.widget.TreeContextMenu");


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

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

3、建立TreeSelector事件处理函数

  1. functiontreeSelectFired(){
  2. //getareferencetothetreeSelectorandgettheselectednode
  3. vartreeSelector=dojo.widget.manager.getWidgetById('treeSelector');
  4. vartreeNode=treeSelector.selectednode;
  5. //getareferencetothesongdisplaydiv
  6. varhostDiv=document.getElementById("songdisplay");
  7. varisFolder=treeNode['isFolder'];
  8. //alert(isFolder);
  9. if(!isFolder){
  10. varsong=treeNode['title'];
  11. varurl=treeNode['url'];
  12. link(url);
  13. }else{
  14. }
  15. }

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

  1. functioninit(){
  2. //getareferencetothetreeSelector
  3. vartreeSelector=dojo.widget.manager.getWidgetById('treeSelector');
  4. //connecttheselecteventtothefunctiontreeSelectFired()
  5. dojo.event.connect(treeSelector,'select','treeSelectFired');
  6. }
  7. dojo.addOnLoad(init);


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

1、Gnmk.java中tree的属性

  1. privateStringid;
  2. privateStringgnmkdm;//功能模块代码
  3. privateStringgnmksm;//功能模块说明
  4. privateStringgnmktb;//功能模块图标
  5. privateStringgnmklj;//功能模块路径
  6. privateStringgnmkmc;//功能模块名称
  7. privateStringgnmksj;//功能模块上级代码
  8. privateStringgnmkbz;//功能模块标志(‘N’为叶节点)

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

  1. CREATETABLEGNMK(IDVARCHAR,GNMKDMVARCHAR,GNMKMCVARCHAR,GNMKLJVARCHAR,GNMKTBVARCHAR,GNMKBZVARCHAR,GNMKSJVARCHAR);
  2. INSERTINTOGNMKVALUES('d098a59f0b765c30010b765d6b780001','01','一级目录1',null,'system.gif','Y','');
  3. INSERTINTOGNMKVALUES('d098a59f0b765e68010b765fda830001','0101','二级目录1','cxtjAction.do','N','01');
  4. INSERTINTOGNMKVALUES('d098a59f0b765e68010b765fda830001','0102','二级目录2','01');
  5. INSERTINTOGNMKVALUES('d098a59f0b765c30010b765d6b780002','02','一级目录2','');
  6. INSERTINTOGNMKVALUES('d098a59f0b765e68010b765fda830002','0201','02');
  7. INSERTINTOGNMKVALUES('d098a59f0b765e68010b765fda830002','0202','02');
  8. INSERTINTOGNMKVALUES('d098a59f0b765e68010b765fda830002','020201','三级目录1','0202');
  9. INSERTINTOGNMKVALUES('d098a59f0b765e68010b765fda830002','020202','三级目录2','0202');

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

  1. publicclassTreeServletextendsHttpServlet{
  2. privatestaticfinallongserialVersionUID=1L;
  3. protectedvoiddoGet(HttpServletRequestrequest,
  4. HttpServletResponseresponse)throwsservletexception,IOException{
  5. Stringaction=request.getParameter("action");
  6. System.out.println("actionb=>"+action);
  7. System.out.println("actionb=>"+action);
  8. Stringdata=request.getParameter("data");
  9. if(action.equalsIgnoreCase("getChildren")){
  10. JSONTokenerjsonTokener=newJSONTokener(data);
  11. JSONObjectjsonObject=(JSONObject)jsonTokener.nextValue();
  12. JSONObjectparentNodeObject=(JSONObject)jsonObject.get("node");
  13. response.setContentType("text/json;charset=gb2312");
  14. PrintWriterout=response.getWriter();
  15. out.write(getChildren(parentNodeObject));
  16. }else{
  17. }
  18. }
  19. privateStringgetChildren(JSONObjectparentNodeObject){
  20. JSONArrayresult=newJSONArray();
  21. StringparentObjectId=parentNodeObject.getString("objectId");//id唯一
  22. //StringparentWidgetId=parentNodeObject.getString("widgetId");//dm
  23. parentObjectId=parentObjectId.equalsIgnoreCase("root")?""
  24. :parentObjectId;
  25. System.out.println("parentObjectId=>"+parentObjectId);
  26. //获取功能模块
  27. ListlistGnmk=this.getGnmkByParent(parentObjectId);
  28. System.out.println("listGnmk=>"+listGnmk.size());
  29. if(listGnmk!=null){
  30. IteratoritGnmk=listGnmk.iterator();
  31. while(itGnmk.hasNext()){
  32. Gnmkqxgnmk=(Gnmk)itGnmk.next();
  33. try{
  34. JSONObjectjsonGnmkObject=newJSONObject();
  35. Stringgnmkbz=qxgnmk.getGnmkbz();
  36. booleanisFolder=gnmkbz.equalsIgnoreCase("Y")?true
  37. :false;
  38. jsonGnmkObject.put("title",qxgnmk.getGnmkmc());
  39. jsonGnmkObject.put("isFolder",isFolder);
  40. jsonGnmkObject.put("widgetId",qxgnmk.getGnmkdm());
  41. jsonGnmkObject.put("objectId",qxgnmk.getGnmkdm());
  42. jsonGnmkObject.put("childIconSrc","images/"
  43. +qxgnmk.getGnmktb());
  44. jsonGnmkObject.put("url",qxgnmk.getGnmklj());
  45. result.put(jsonGnmkObject);
  46. }catch(JSONExceptione){
  47. e.printstacktrace();
  48. }
  49. }
  50. }
  51. returnresult.toString();
  52. }
  53. privateListgetGnmkByParent(Stringgnmksj){
  54. GnmkDAOgnmkDao=newGnmkDAO();
  55. returngnmkDao.getGnmkByParent(gnmksj);
  56. }
  57. }


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

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

  1. publicvoidcontextinitialized(ServletContextEventevent){
  2. try{
  3. //loadthedriver
  4. Class.forName("org.hsqldb.jdbcDriver");
  5. //createthetableandaddsampledata
  6. InputStreamReaderin=newInputStreamReader(getClass().getClassLoader().getResourceAsstream("db.sql"));
  7. BufferedReaderreader=newBufferedReader(in);
  8. dbutils.setupDatabase(reader);
  9. }catch(ClassNotFoundExceptione){
  10. e.printstacktrace();
  11. }
  12. }

2、web.xml相关配置

  1. <listener>
  2. <listener-class>
  3. dojo.sample.ContextListener
  4. listener-class>
  5. >

相关文章

我有一个网格,可以根据更大的树结构编辑小块数据.为了更容易...
我即将开始开发一款教育性的视频游戏.我已经决定以一种我可以...
我正在使用带有Grails2.3.9的Dojo1.9.DojoNumberTextBox小部...
1.引言鉴于个人需求的转变,本系列将记录自学arcgisapiforja...
我正在阅读使用dojo’sdeclare进行类创建的语法.描述令人困惑...
我的团队由更多的java人员和JavaScript经验丰富组成.我知道这...