[知了堂学习笔记]_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>

界面效果:
EasyUI布局

在搭建好如上面所示的界面之后,就可以在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中的Tree Lines

阅读全文
0 0
原创粉丝点击