基于 jQuery zTree 构建动态加载的树

fmms 13年前

一.下载、安装zTree

zTree下载地址:http://code.google.com/p/jquerytree/downloads/list

这里我下载的是JQuery zTree v3.0。目前最新版是v3.1,一般不建议使用最新版。

下载完成后解压,可以看到其中有三个文件夹和一个更新日志文件。

Css文件夹  zTree的样式和图片存放位置

Demo文件夹 存放zTree的一些实例

Js文件夹    存放的是所有与zTree相关的js文件。这里min是压缩版,我们在开发的时候建议使用未压缩版的(不含min的)。

 

开发时建议将这些压缩包统一放在一个文件夹(比如zTree)下,这样,如果需要查看对应的实例,可直接在当前工程下访问并做修改,便于开发使用。当然,开发完成后可以删除demo内容。

 

二.编辑页面

 

<%@ page language="java" pageEncoding="UTF-8"%>  <%@taglib uri="/struts-tags" prefix="s"%>  <%@ include file="../common/header.jsp" %>    <!DOCTYPE html>  <HTML>  <HEAD>   <title>指派权限</title>   <meta http-equiv="content-type" content="text/html; charset=UTF-8">      <link rel="stylesheet" type="text/css" href="${root}/css/dialogStyle.css"/>   <link rel="stylesheet" href="${root}/js/zTree/css/zTreeStyle/zTreeStyle.css" type="text/css">   <link rel="stylesheet" type="text/css" href="${root}/js/jquery/themes/icon.css" />   <STYLE type="text/css">    .btn {     BACKGROUND: url(../images/bt_bg.gif);      BORDER-RIGHT: #999999 1px solid;      PADDING-RIGHT: 2px;      BORDER-TOP: #CCCCCC 1px solid;      PADDING-LEFT: 2px; FONT-SIZE: 12px;      FILTER: progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr=#ffffff, EndColorStr=#cecfde);      BORDER-LEFT: #CCCCCC 1px solid;      CURSOR: hand; COLOR: black;      PADDING-TOP: 2px;      BORDER-BOTTOM: #999999 1px solid;    }   </STYLE>      <!--    为提高效率,建议将1.4.4换成1.6.4版   <script type="text/javascript" src="${root}/js/zTree/js/jquery-1.4.4.min.js"></script>    -->   <script type="text/javascript" src="${root}/js/jquery/jquery-1.6.4.min.js"></script>   <script type="text/javascript" src="${root}/js/jquery/jquery.easyui.min.js"></script>   <script type="text/javascript" src="${root}/js/zTree/js/jquery.ztree.core-3.0.js"></script>   <script type="text/javascript" src="${root}/js/zTree/js/jquery.ztree.excheck-3.0.js"></script>   <script type="text/javascript" src="${root}/js/winutil.js"></script>     <!--   <script type="text/javascript" src="${root}/js/js/jquery.ztree.exedit-3.0.js"></script>   -->   <SCRIPT type="text/javascript">    <!--    var setting = {     async: {      enable: true,//异步处理        //contentType: "application/json",//提交参数方式,这里 JSON 格式,默认form格式            url: '${root}/sys/listoper.action?roleId=${roleId}',//异步获取json格式数据的路径        autoParam: ["id","name"]//异步加载时需要提交的参数,多个用逗号分隔              },     callback: {//回调函数,在这里可做一些回调处理      //beforeAsync: zTreeBeforeAsync     },     check: {//设置 zTree 的节点上是否显示 checkbox / radio ,默认为false      enable: true     },     data: {      simpleData: {       /**       如果设置为 true,请务必设置 setting.data.simpleData 内的其他参数: idKey / pIdKey / rootPId       并且让数据满足父子关系。*/            enable: true,//true / false 分别表示 使用 / 不使用 简单数据模式       idKey: "id",       pIdKey: "pId",       rootPId: 0             }     }    };      var zNodes =[];//树节点,json格式,异步加载可设置为null或[]     var zTreeObj;//树对象        $(document).ready(function(){          zTreeObj = $.fn.zTree.init($("#permission_tree"), setting, zNodes);//实例化后直接返回树对象       //异步提交表单     $('#permissionform').form({            url: '${root}/sys/PermissionManagerole.action',            onSubmit: function() {             //获取树对象中选中的节点       var nodes = zTreeObj.getCheckedNodes();       var s = '';//选中节点ids       //遍历选中的节点,为s赋值       for(var i=0; i<nodes.length; i++){        if (s != '') s += ',';        s += nodes[i].id;       }       document.all("roledto.permissionIds").value = s;            },            success: function(data) {             //操作成功,返回信息             var data = jQuery.parseJSON(data);             if(data.success == false){              alert(data.msg);             }               m_close();              }        });            });      //-->   </SCRIPT>  </HEAD>    <BODY onunload="m_close()" style="background-color: #f7f7f7;">    <div style="border: 0px ;width: 100%;height:100%;background-color: #f7f7f7;">       <!-- 树加载后存放的容器 -->    <ul id="permission_tree" class="ztree" style="border: 0px; background-color: #f7f7f7;"></ul>        <!-- 提交授权操作表单 -->     <form id="permissionform" method="post">     <table>      <tr>       <td><input type="hidden" name="roledto.permissionIds" /></td>       <td><input type="hidden" name="roledto.roleId" value="${roleId}"/></td>       <td><input type="hidden" name="orgid" value="${orgId}"/></td>      </tr>      <tr>       <td width="100%" align="right">        <input type="submit" style="width:60px;" class="btn" value="保存"/>&nbsp;        <input type="button"  style="width:60px;"  class="btn" value="取消" onclick="m_close()"/>       </td>      </tr>     </table>    </form>                </div>    </BODY>  </HTML>

三.后台Action

private String id;      private String roleId;      /**    * 显示权限栏目树    * 这里采用一次加载所有树节点的方式    * 当然也可以换成逐级动态加载的方式    * @return    * @throws IOException    */   @SuppressWarnings("unchecked")   public String list() throws IOException{        /**     * 再次查询时直接返回,这里采用所有节点一次加载的方式     * @param id 点击树的节点时传递到后台的属性id     */    if(ValidateUtil.validateString(id)){     return SUCCESS;    }    //根据角色找到对应的操作权限id    String operationids = this.getOperationIdsByRoleId(roleId);    //查询所有的权限分类,如系统管理、订单管理、采购管理等等,作为树的一级节点    List<OperationClass> list =operationClassServiceImpl.getAllOperationClass();    //存放树节点信息    List<Map<String,Object>> items = new ArrayList<Map<String,Object>>();    //当前角色对应的操作    List<RoleOperation> rolist = this.roleServiceImpl.getRoleOperationByRoleId(roleId);              for(OperationClass node: list){   //第一级遍历,遍历所有的权限分类                      Map<String,Object> item = new HashMap<String,Object>();   //最外层,父节点                       item.put("id", node.getOperationClassId());//id属性  ,数据传递              item.put("name", node.getClassName()); //name属性,显示节点名称              item.put("isParent", true);//设置为父节点,这样所有最外层节点都是统一的图标,看起来会舒服些              //item.put("iconSkin", "diy02");//设置节点的图标皮肤, diy02在zTreeStyle.css中进行设置                            /**               * 如果当前节点(权限分类)有对应的操作(权限),添加操作权限作为该节点的子节点               */              if (node.getOperations()!=null&&node.getOperations().size()>0){                                      Iterator<Operation> it = node.getOperations().iterator();                  //存放第一层子节点信息                  List<Map<String,Object>> subitems = new ArrayList<Map<String,Object>>();                                    while(it.hasNext()){//对操作进行遍历                                      Map<String,Object> subitem = new HashMap<String,Object>();//第二层                   Operation oper = (Operation) it.next();                   subitem.put("id", oper.getOperationId()+":oper");//id属性  ,数据传递                   subitem.put("name", oper.getOperationName()); //name属性,显示节点名称                                      /**                    * 如果操作中有多个选项,添加选项作为第二层的子节点                    */                   if(oper!=null&&oper.getOptions()!=null){                    String uoption = "";//有操作权限的操作选项                    for(RoleOperation ro : rolist){                     if(ro.getOperation().getOperationId().                      equals(oper.getOperationId())){//如果当前角色有对应的操作                      uoption = ro.getOptions();                     }                    }                    String[] suboper = oper.getOptions().split(",");              List<Map<String,Object>> items3 = new ArrayList<Map<String,Object>>(); //第三层              for(int i=0;i<suboper.length;i++){               Map<String,Object> item3 = new HashMap<String,Object>();               item3.put("id", "opt:"+oper.getOperationId()+":"+suboper[i]);//id属性  ,数据传递               item3.put("name", suboper[i]); //name属性,显示节点名称                 if(uoption!=null&&!"".equals(uoption)){//如果操作中有操作选项             if(uoption.contains(suboper[i]+",")){//如果当前角色有此操作选项              item3.put("checked", true);//将此选项选中             }               }               items3.add(item3);//添加到树的第三层              }                subitem.put("children", items3);//添加第二层子节点                                 }else{//如果操作没有选项                    if(operationids.contains(oper.getOperationId())){//当前角色有此操作                     subitem.put("checked", true);//将此操作选中                 }                   }                   subitems.add(subitem);//添加到树的第二层                  }                  item.put("children", subitems);//添加第一层子节点                                }                items.add(item); //添加到树的第一层                          }          JSONArray json = JSONArray.fromObject(items);//转成json格式          jsonString = json.toString();//json格式字符串              return SUCCESS;   }

四.编后语

 

公司之前用的jQuery dTreedTree也是比较好用的,跟zTree的区别不是很大。但有一点比较让人难以忍受,dTree在页面的解析效率比较低。在权限操作这一块儿换成zTree后速度提高了好几倍。

zTree的具体使用已在页面和action模块做了细致的说明,如果对其中的用法比较有疑问可以查看官方的api,中文api地址如下:http://www.baby666.cn/v3/api.php</a></span>,或者也可以给我留言,我们共同探讨。

转自:
http://hbxflihua.iteye.com/blog/1416383</span></span>