[知了堂学习笔记]_EasyUi快速搭建一个权限管理的模块(3)--菜单树效果的实现

一、如何通过代码实现导航栏菜单树


在前面,我们介绍了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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值