[知了堂学习笔记]_EasyUi快速搭建一个权限管理的模块(3)--菜单树效果的实现
来源:互联网 发布:office for mac 威锋 编辑:程序博客网 时间:2024/06/05 17:07
一、如何通过代码实现导航栏菜单树
在前面,我们介绍了easyUI 的Tree lines 的使用,知道EasyUI 前框框架要生成对应的tree结构,就需要有对应的json数据格式,这一节我们主要解释一下怎么实现这个过程。主要的过程就是将数据库中的数据转变成为对应的json格式数据。
再次之前,还得再加上如何使用EasyUI快速搭建好我们的主界面。直接看一段代码:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>使用完整页面创建布局</title> <link rel="stylesheet" type="text/css" href="../easyui/themes/default/easyui.css"> <link rel="stylesheet" type="text/css" href="../easyui/themes/icon.css"> <link rel="stylesheet" type="text/css" href="../easyui/demo/demo.css"> <script type="text/javascript" src="../easyui/jquery.min.js"></script> <script type="text/javascript" src="../easyui/jquery.easyui.min.js"></script></head><body class="easyui-layout"><div data-options="region:'north',title:'North Title',split:true" style="height:100px;"></div><div data-options="region:'south',title:'South Title',split:true" style="height:100px;"></div><div data-options="region:'west',title:'West',split:true,collapsible:false" style="width:15%;"></div><div data-options="region:'center',title:'center title'" style="padding:5px;background:#eee;"> sjsssfsj</div></body></html>
界面效果:
在搭建好如上面所示的界面之后,就可以在West的div中生成对应的Tree树格式。
二、生成Tree Lines所需的json数据格式
这个时候,我们就需要再次对我们数据库中的权限表再次做一个解释,里面的字段设置的意义:
(1)权限表中authId与parentId的关系
parentId中的数据对应着的是authId。例如:权限管理这条数据。parentId=1,此时的1对应的是authId的1,说明此节点的父节点是authId=1的某系统。类似的,其他的菜单。parentId对应的就是父节点authId。
(2)authPath的用法。
在easyUI中的树的规范中,提到过一个自定义属性。将authPath放在自定义属性中,主要是为了页面中完成点击事件,实行跳转的功能。
例如这下面的一段代码:当页面加载的时候,调用Ajax请求数据库,获取到数据库中authId表的数据,封装成对应的json格式的数据。然后定义点击事件,通过点击事件,用js创建选项卡的方式,传入该节点的自定义属性中的页面的路径,完成打开本地写好的页面,完成该权限对应的操作。
$("#tree").tree({ lines:true, url:'AuthServlet?action=menu&parentId=-1', onLoadSuccess:function(){ $("#tree").tree('expandAll'); }, onClick:function(node){ console.log(node); if(node.id==16){ logout(); }else if(node.id==15){ openPasswordModifyDialog(); }else if(node.attributes.authPath){ openTab(node); } } });//============================================================function openTab(node){ if($("#tabs").tabs("exists",node.text)){ $("#tabs").tabs("select",node.text); }else{ var content="<iframe frameborder=0 scrolling='auto' style='width:100%;height:100%' src="+node.attributes.authPath+"></iframe>" $("#tabs").tabs("add",{ title:node.text, iconCls:node.iconCls, closable:true, content:content }); } }});
(3)state的用法。
通过观察,我们可以发现,当state的值为open的时候,对应带easyUI中的tree中的节点,是没有子节点的。当state的值为closed的时候,说明该条数据中对应的tree对应的节点是有子节点的。具体对应到封装json数据格式的时候,我们在算法中细讲。
(4)iconCls的使用。
这个要和easyUI中自定义的图标相联系。在引入easyUI的框架的时候,前面会引入这样的一样代码。
<link rel="stylesheet" type="text/css" href="easyui/themes/icon.css">
在对应的文件夹下面的css样式表中,定义了很多默认的图标样式,要使用自定义的样式就需要在里面自己做定义。如下面的代码:
.icon-home{ background:url('usericons/home.png') no-repeat center center;}.icon-permission{ background:url('usericons/permission.png') no-repeat center center;}.icon-student{ background:url('usericons/student.png') no-repeat center center;}.icon-course{ background:url('usericons/course.png') no-repeat center center;}.icon-item{ background:url('usericons/item.png') no-repeat center center;}.icon-userManage{ background:url('usericons/userManage.png') no-repeat center center;}.icon-roleManage{ background:url('usericons/roleManage.png') no-repeat center center;}.icon-menuManage{ background:url('usericons/menuManage.png') no-repeat center center;}.icon-modifyPassword{ background:url('usericons/modifyPassword.png') no-repeat center center;}.icon-exit{ background:url('usericons/exit.png') no-repeat center center;}
是不是可以通过比较发现,这里定义的类名,和authId中存放的iconCls中的数据只有关联的。
三、如何通过代码实现
1、进入调试,进入到调用生成tree的json方法:传入的参数:
int userId:----当前用户的登录的用户的id
string parentId:-----传入的父节点的id,开始调用的时候为最高一级的父节点的id。
通过userId和parentId父节点生成json对应的数据格式的方法:public JSONArray getAuthsByUserId(int userId,String parentId) { JSONArray jsonArray=this.getAuthByParentId(userId, parentId); for(int i=0;i<jsonArray.size();i++){ JSONObject jsonObject=jsonArray.getJSONObject(i); if("open".equals(jsonObject.getString("state"))){ continue; }else{ jsonObject.put("children", getAuthsByUserId(userId,jsonObject.getString("id"))); } } return jsonArray; }
2、进入到getAutsByUserId()方法之后,第一次通过调用本类中的getAuthByParentId()方法获取ParentId为-1的,并且userId为当前用户的Id的json格式数据。
public JSONArray getAuthByParentId(int userId,String parentId){ JSONArray jsonArray=new JSONArray(); String sql="SELECT t_auth.authId,t_auth.authName,t_auth.authPath,t_auth.parentId,t_auth.authDescription,t_auth.state,t_auth.iconCls " + "FROM t_roleuser LEFT JOIN t_role ON t_roleuser.roleId=t_role.roleId " + "LEFT JOIN t_authrole ON t_role.roleId=t_authrole.roleId " + "LEFT JOIN t_auth ON t_authrole.authId=t_auth.authId " + "WHERE t_auth.parentId=? AND t_authrole.roleId=?"; Connection con=null; PreparedStatement pstmt; ResultSet rs; try { con = dataSource.getCurrentConnection(); pstmt = con.prepareStatement(sql); pstmt.setString(1, parentId); pstmt.setInt(2, userId); rs=pstmt.executeQuery(); while(rs.next()){ JSONObject jsonObject=new JSONObject(); jsonObject.put("id", rs.getInt("authId")); jsonObject.put("text", rs.getString("authName")); if(!hasChildren(userId ,rs.getString("authId"))){ jsonObject.put("state", "open"); }else{ jsonObject.put("state", rs.getString("state")); } jsonObject.put("iconCls", rs.getString("iconCls")); JSONObject attributeObject=new JSONObject(); attributeObject.put("authPath", rs.getString("authPath")); jsonObject.put("attributes", attributeObject); jsonArray.add(jsonObject); } } catch (SQLException e) { e.printStackTrace(); }finally{ dataSource.closeConnection(con); } return jsonArray; }
3、顶用方法之后,在做是否有子节点判断的时候,有一个方法hasChildren(),判断该节点是否子节点,并为这个节点设置相应的状态。下面一段代码为hasChildren()方法的代码:
//判断是否有Children属性: private boolean hasChildren(int userId,String parentId ){ String sql="SELECT t_auth.authId,t_auth.authName,t_auth.authPath,t_auth.parentId,t_auth.authDescription,t_auth.state,t_auth.iconCls " + "FROM t_roleuser LEFT JOIN t_role ON t_roleuser.roleId=t_role.roleId " + "LEFT JOIN t_authrole ON t_role.roleId=t_authrole.roleId " + "LEFT JOIN t_auth ON t_authrole.authId=t_auth.authId " + "WHERE t_auth.parentId=? AND t_authrole.roleId=?"; Connection con=null; PreparedStatement pstmt; ResultSet rs; try { con= dataSource.getCurrentConnection(); pstmt = con.prepareStatement(sql); pstmt.setString(1, parentId); pstmt.setInt(2, userId); rs=pstmt.executeQuery(); return rs.next(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ dataSource.closeConnection(con); } return false; }
4、回到通过servlet进入到dao层查询tree的json方法中,在方法中第一次调用getAuthsByUserId之后的到的json数据格式为:
[ { "id": 1, "text": "某系统", "state": "closed", "iconCls": "icon-home", "attributes": { "authPath": "" } }]
第一次调用完getAuthsByUSerId方法之后的得到的json数据格式为tree中的最顶级的菜单。然后我们回到我们查询tree的json格式的函数,里面有个一For循环,通过循环每次返回的json格式的数据,通过判断json格式中的state的值是否为“closed”来判断是否有子节点,如果有子节点,则再次调用getAuthsByUserId方法获取该节点下的子节点的对应的json格式数据。实现该功能的代码我们在粘贴一遍,这段代码是我们第一次进入到dao层的方法中的一段,我们也可以看前面的方法。
for(int i=0;i<jsonArray.size();i++){ JSONObject jsonObject=jsonArray.getJSONObject(i); if("open".equals(jsonObject.getString("state"))){ continue; }else{ jsonObject.put("children", getAuthsByUserId(userId,jsonObject.getString("id"))); } }
5、通过这样递归的方法之后,我们就会发现,我们最后得到的json 数据格式的就是我们所需要的数据格式,也就是我们最开始看到的json数据格式。成功之后,我们就会得到这样的效果:
- [知了堂学习笔记]_EasyUi快速搭建一个权限管理的模块(3)--菜单树效果的实现
- [知了堂学习笔记]_EasyUi快速搭建一个权限管理的模块(2)--界面效果以及如何做出菜单树效果
- [知了堂学习笔记]_EasyUi快速搭建一个权限管理的模块(1)--RBAC概述和数据库设计
- [知了堂学习笔记]_break的用法
- [知了堂学习笔记]_JS的数据类型
- [知了堂学习笔记] jQuery的事件
- [知了堂学习笔记]_jQuery的事件
- [知了堂学习笔记] 二叉树建立及其遍历的思路和实现
- [知了堂学习笔记]_css3特效第一篇--旋转的背景&翻书效果
- [知了堂学习笔记]_mybatis_02如何快速搭建mybatis框架之一
- [知了堂学习笔记]_mybatis_03如何快速搭建mybatis框架之二
- [知了堂学习笔记]_Java中session的学习
- 【知了堂学习笔记】_Java中cookie的学习
- 【知了堂学习笔记】_Java中ServletContext的学习
- [知了堂学习笔记]_Java代码实现MySQL数据库的备份与还原
- 【知了堂学习笔记】CSS3令人眼前一亮的网页文字效果
- 【知了堂学习笔记】String的创建过程—第一章
- [知了堂学习笔记]_记一次BootStrap的使用
- 学习笔记---css中清除浮动
- Laravel CSRF
- 大整数类
- 历年阿里面试题汇总(2017年不断更新中)
- 有趣的javascript API
- [知了堂学习笔记]_EasyUi快速搭建一个权限管理的模块(3)--菜单树效果的实现
- SpringMVC导入Excel文件到MySQL
- grails框架学习重点知识点
- 二、Servlet生命周期
- Css中属性继承
- 网易校招第3题
- 五、maven项目搭建 ssm框架之spring整合redis
- HDU 2899 Strange fuction(三分模版)
- 使用haystack实现django全文检索搜索引擎功能