在项目开发中,对于整体的页面布局中对于菜单导航栏我们一般设计为根据不同的用户权限展示不同的菜单选项,同时菜单显示也会做异步加载处理。本文就来介绍下基于EasyUI的tree插件来实现导航栏的异步加载实现。
EasyUI中tree的异步加载
1.实现效果
首先我们来看下最终的实现效果,具体如下。
2.表结构设计
因为在tree插件显示数据的时候对应查询的json数据的字段有要求,具体参考官网:http://www.jeasyui.net/plugins/185.html ,所以为了避免查询的数据和需要显示的数据不一致而造成的数据的转换,所以在设计表结构的时候可以注意下。菜单的结构如下:
测试数据
3.服务端处理
通过mybatis的逆向工程生成相关的接口,映射文件和pojo文件等。然后在controller中定义处理请求的方法,接收查询菜单的id。返回JSON数据,如下:
/** * 异步查询菜单【node】信息 * @param id * @return */ @RequestMapping("/getNode") @ResponseBody public List<Menu> getNode(Integer id){ Menu menu = new Menu(); if(id !=null && id > 0){ menu.setParentId(id); }else{ menu.setParentId(0); } return menuService.query(menu); }
然后在控制器中具体处理请求
public List<Menu> query(Menu menu) { MenuExample example = new MenuExample(); MenuExample.Criteria criteria = example.createCriteria(); if(menu!=null){ if(menu.getParentId()!=null ){ // 根据父菜单编号查询 criteria.andParentIdEqualTo(menu.getParentId()); }else{ criteria.andParentIdEqualTo(0); } } return menuMapper.selectByExample(example); }
4.页面js代码实现
home界面的主要代码如下:
<body class="easyui-layout"> <!-- 顶部 Logo --> <div data-options="region:'north',border:true,split:true" style="height: 100px;background: url(img/logo.png) no-repeat 0% 50%; "> <div class="topNav" style="border: 0px red solid; width: 230px; height: 80px; line-height:80px; float: right;"> <a href="https://www.itbaizhan.com/" target="_blank" style="color:red">百战程序员</a> | <a href="#"><shiro:principal property="username"></shiro:principal></a> | <a href="logout.do"> 安全退出 </a> </div> </div> <!-- 右侧 菜单栏 --> <div data-options="region:'west',title:'导航栏',split:true" style="width: 180px;"> <ul id="tt" class="easyui-tree"> <!-- 动态加载数据 --> </ul> </div> <!-- 中间 内容主体 --> <div data-options="region:'center',border:false" style="padding: 0px; background: #eee;"> <div id="tabs" class="easyui-tabs" data-options="fit:true" style="width:500px;height:250px;"> <div title="首页" style="padding:20px;display:none;"> 欢迎光临 </div> </div> </div> <script type="text/javascript"> function goTabs(path,title){ // 动态添加一个标签页 var isSelect = $("#tabs").tabs('exists', title); // 添加一个新的标签页面板(tab panel) if(isSelect){ $("#tabs").tabs('select', title); return; }else{ $('#tabs').tabs('add',{ title:title, content:'<iframe src="'+path+'" width="100%" height="100%" style="border: 0px;"></iframe>', closable:true, //刷新按钮 tools: [{ iconCls: 'icon-mini-refresh', handler: function(){ var currentTab = $('#tabs').tabs('getSelected'); RefreshTab(currentTab); } }] }); } } //刷新当前标签Tabs function RefreshTab(currentTab) { var url = $(currentTab.panel('options')).attr('href'); $('#tabs').tabs('update', { tab: currentTab, options: { href: url } }); currentTab.panel('refresh'); } $(function(){ // 动态添加菜单 $("#tt").tree({ url: "/sys/menu/getNode", onClick: function(node){ if(node.url != null && node.url != '' ){ // 打开一个新的窗口 goTabs(node.url+"/go",node.text); } } }); }); </script> </body> </html>
加载导航菜单的核心代码:
// 加载菜单数据 state:closed是关键 $(function(){ // 动态添加菜单 $("#tt").tree({ url: "/sys/menu/getNode", onClick: function(node){ if(node.url != null && node.url != '' ){ // 打开一个新的窗口 goTabs(node.url+"/go",node.text); } } }); }); // 点击子菜单开的一个新窗口的代码 function goTabs(path,title){ // 动态添加一个标签页 var isSelect = $("#tabs").tabs('exists', title); // 添加一个新的标签页面板(tab panel) if(isSelect){ $("#tabs").tabs('select', title); return; }else{ $('#tabs').tabs('add',{ title:title, content:'<iframe src="'+path+'" width="100%" height="100%" style="border: 0px;"></iframe>', closable:true, //刷新按钮 tools: [{ iconCls: 'icon-mini-refresh', handler: function(){ var currentTab = $('#tabs').tabs('getSelected'); RefreshTab(currentTab); } }] }); } } //刷新当前标签Tabs function RefreshTab(currentTab) { var url = $(currentTab.panel('options')).attr('href'); $('#tabs').tabs('update', { tab: currentTab, options: { href: url } }); currentTab.panel('refresh'); }
因为我们的表结构设计的tree默认的字段是一致的所以省略掉了转换的过程,如果不一致还需要将查询的数据转换为满足tree展示的数据要求。至于根据账号的权限来查询不同的菜单仅仅只需要在业务逻辑层加上账号的条件即可了。