WEB开发中前后台树形菜单的展示设计
在WEB开发中经常需要进行树形菜单的展示,本例通过不同角度的总结了如下三种实现方式:
- 通过JS的递归实现前端菜单DOM的动态创建
- 通过JSP的include指令结合JSTL表达式语言递归实现菜单的展示
- 通过扩展JSP的标签在后端实现菜单的DOM节点并响应给前端展示
针对第一种方法,可以采用JS的相关组件,或者使用JS的递归调用将服务端相应的数据组装成DOM节点内容,动态添加到菜单的Container中,网上的例子较多,在此不再赘述,本例就后两种方案进行讲解。
通过JSP的include指令结合JSTL表达式语言递归实现菜单的展示
由于JSP中的JSTL不支持递归,又不想在JSP中加入Java脚本,可以采用JSP动态包含的方式组装菜单,当前方案需要服务端将菜单列表组装成树形结构,具体算法如下:
主页面menu.jsp
<ul class="nav nav-list">
<c:if test="${not empty sessionScope.SESSION_MENUS}">
<c:forEach items="${sessionScope.SESSION_MENUS }" var="menu">
<%@include file="recursiveMenu.jsp"%>
</c:forEach>
</c:if>
</ul><!-- /.nav-list -->
递归调用页面recursiveMenu.jsp
<%@ page language="java" import="java.util.*" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<li>
<c:choose>
<c:when test="${empty menu.children }">
<a href="${menu.url }">
<i class="${menu.icon }"></i>
<span class="menu-text"> ${menu.name } </span>
</a>
</c:when>
<c:otherwise>
<a href="javascript:void(0);" class="dropdown-toggle">
<i class="${menu.icon }"></i>
<span class="menu-text"> ${menu.name } </span>
<b class="arrow icon-angle-down"></b>
<ul class="submenu">
<c:forEach items="${menu.children }" var="menu">
<c:set var="menu" value="${menu}" scope="request"/>
<jsp:include page="recursiveMenu.jsp"/>
</c:forEach>
</ul>
</a>
</c:otherwise>
</c:choose>
</li>
通过扩展JSP的标签在后端实现菜单的DOM节点并相应给前端展示
当前方案采用扩展JSP标签的方式实现具体实现方法如下
1、新建标签实现类MenuTa.java
package com.luwei.console.mg.tag; import java.io.IOException;
import java.util.List; import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport; import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import com.luwei.console.mg.constant.KeyConst;
import com.luwei.console.mg.entity.ext.MenuExt; /**
* <Description> 菜单标签<br>
*
* @author lu.wei<br>
* @email 1025742048@qq.com <br>
* @date 2016年12月25日 <br>
* @since V1.0<br>
* @see com.luwei.console.mg.tag <br>
*/
public class MenuTag extends TagSupport {
private Logger logger = LoggerFactory.getLogger(this.getClass()); /**
* serialVersionUID <br>
*/
private static final long serialVersionUID = -2755997672501044414L; @SuppressWarnings("unchecked")
@Override
public int doStartTag() throws JspException {
Object menusObj = pageContext.getSession().getAttribute(KeyConst.KEY_SESSION_MENUS);
if (null != menusObj) {
List<MenuExt> menus = (List<MenuExt>) menusObj;
String menuStr = assumbleMenuHtml(menus);
try {
pageContext.getOut().println(menuStr);
}
catch (IOException e) {
logger.error("菜单标签创建菜单出错:{} ", e.getMessage(), e);
}
}
return super.doStartTag();
} /**
* <Description> TODO<br>
*
* @author lu.wei<br>
* @email 1025742048@qq.com <br>
* @date 2016年12月25日 上午9:29:26 <br>
* @param menus
* @return <br>
*/
private String assumbleMenuHtml(List<MenuExt> menus) {
StringBuffer sb = new StringBuffer(""); if (!menus.isEmpty()) {
long activeMenuId = 1;
Object avtiveMenuIdObj = pageContext.getSession().getAttribute(KeyConst.SESSION_ACTIVE_MENU_ID);
if (null != avtiveMenuIdObj) {
activeMenuId = (Long) avtiveMenuIdObj;
}
for (MenuExt menu : menus) { if (menu.getId() == activeMenuId) {
sb.append("<li class='active'>");
}
else {
sb.append("<li>");
} boolean hasChild = false;
if (null != menu.getChildren() && !menu.getChildren().isEmpty()) {
hasChild = true;
}
if (hasChild) {
sb.append("<a href='#' class='dropdown-toggle'> ");
}
else {
String url = menu.getUrl();
if (StringUtils.isNotEmpty(url)) {
if (url.contains("?")) {
url = (url + "&mid=" + menu.getId());
}
else {
url = (url + "?mid=" + menu.getId());
}
}
sb.append("<a href='").append(url).append("'>");
} if (StringUtils.isNotEmpty(menu.getIcon())) {
sb.append("<i class='").append(menu.getIcon()).append("'></i>");
}
sb.append("<span class='menu-text'>").append(menu.getName()).append("</span>");
if (hasChild) {
sb.append("<b class='arrow icon-angle-down'></b>");
}
sb.append("</a>");
if (hasChild) {
sb.append("<ul class='submenu'>").append(assumbleMenuHtml(menu.getChildren())).append("</ul>");
}
sb.append("</li>");
}
}
return sb.toString();
}
}
2、配置标签
在项目的WEB-INFO目录下新建文件treeMenuAssum.tld
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
" http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>1.2</jspversion>
<shortname>menu</shortname>
<uri>http://www.luwei.com/web/ext/menus</uri>
<tag>
<name>menu</name>
<tagclass>com.luwei.console.mg.tag.MenuTag</tagclass>
</tag>
</taglib>
3、使用菜单标签
在JSP页面中直接使用新建标签
<%@ taglib prefix="menu" uri="http://www.luwei.com/web/ext/menus" %>
<menu:menu/>
总结
以上三种方式均能够实现后端服务的配置管理的无限树形菜单在前端显示出来,第一种方法服务端只需要将数据组装成前端需要的格式相应给前端,前端通过空间或者递归的方式动态创建DOM节点就可以了;二后两种方式采用纯Java相关的知识完全由服务端生成树形菜单,服务端会有一定的负载,同时采用JSP动态包含的方式,如果是在菜单中存在复杂逻辑的话不容易实现,因此推荐使用第一和第三中方案。
具体采用哪种方式可以根据各自项目进行选择,但是实现原理都是相同的。
WEB开发中前后台树形菜单的展示设计的更多相关文章
- web开发中前后端传值
在JavaScript中,页面与页面间的传值需要注意. 比如,我们通过url向下个页面进行传一个数字时,到下个页面进行解析出来后可能是一个字符串.这样会导致一个现象.调试时,发现我要传的值的确传过来了 ...
- web 开发之酷炫--- 酷炫展示
http://www.cnblogs.com/dsxniubility/p/4588560.html
- java web开发_购物车功能实现
java web开发_购物车功能实现 之前没有接触过购物车的东东,也不知道购物车应该怎么做,所以在查询了很多资料,总结一下购物车的功能实现. 查询的资料,找到三种方法: 1.用cookie实现购物车: ...
- 简明易懂,将细节隐藏,面向新手树立web开发概念——学完Java基础语法,超快速上手springboot+mybatiJavaWeb开发
简明易懂,将细节隐藏,面向新手树立web开发概念 --学完Java基础语法,超快速上手JavaWeb开发 Web本质(先忽视各种协议) Web应用可以理解为浏览器和服务器之间的交互. 我们可以看一个简 ...
- Asp.Net Web API开发微信后台
如果说用Asp.Net开发微信后台是非主流,那么Asp.Net Web API的微信后台绝对是不走寻常路. 需要说明的是,本人认为Asp.Net Web API在开发很多不同的请求方法的Restful ...
- C++后台实践:古老的CGI与Web开发
本文写给C/C++程序猿,也适合其他对历史感兴趣的程序猿 ============================================= 谈到web开发,大家首先想到的PHP.JavaEE ...
- 渐进式web应用开发-- 使用后台同步保证离线功能(六)
_ 阅读目录 一:什么是后台同步保证离线功能呢? 二:后台同步是如何实现的呢? 三:如何给sync事件传递数据? 四:在我们的项目中添加后台同步功能 回到顶部 一:什么是后台同步保证离线功能呢? 在我 ...
- 使用ztree展示树形菜单结构
官网:http://www.treejs.cn/v3/main.php#_zTreeInfo 一.功能简介 在权限系统中,实现给角色指定菜单权限的功能.主要包括以下几点: 读取全部菜单项,并以树形结构 ...
- java web 开发三剑客 -------电子书
Internet,人们通常称为因特网,是当今世界上覆盖面最大和应用最广泛的网络.根据英语构词法,Internet是Inter + net,Inter-作为前缀在英语中表示“在一起,交互”,由此可知In ...
随机推荐
- android开发虚拟机不能正常启动
点击 window---perspective---DDMS---查看设备状态, 如果显示没有可用设备,则在AVD manager中重 启即可, 若列表中有设备,但显示offline 可采用一下方式 ...
- windows平台源码编译最新版openssl
本文有问题,待改中................. 1.从openssl官网下载最新版openssl https://www.openssl.org/source/ The latest ...
- nodejs最新教程
脚本模式 以下是我们的第一个Node.js程序: 实例 console.log("Hello World"); 保存该文件,文件名为 helloworld.js, 并通过 node ...
- 【笔记】Service的使用
一.创建Service 1.创建一个myService类,来继承Service.重写其中的方法,包括:onCreate(),onStartCommend(),onDestroy(),onBind()方 ...
- Hello World!
博客园的效率真是高啊,开通博客的申请刚刚递交几分钟就通过了,赞一下博客园的程序员们,这么晚还在工作! 博客主要用来记录自己学习HTML5.CSS.PHP等web前端技术的经历,因为是初学者,所以发的文 ...
- flex(兼容写法)
CSS样式 flex:定义布局为盒模型 flex-v:盒模型垂直布局 flex-1:子元素占据剩余的空间 flex-align-center:子元素垂直居中 flex-pack-center:子元素水 ...
- Exercise 24: More Practice
puts "Let's practice everything." puts 'You\'d need to know \'bout escapes with \\ that do ...
- 转 git安装配置
Win7上Git安装及配置过程 一.安装说明 1.Git在windows平台上安装说明. Git 是 Linux Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件 ...
- iOS Orientation bug
Every September means pain for iOS developers- you need to make sure your old apps/code run on the n ...
- Windows Server 2012 没有远程桌面授权服务器可以提供许可证,远程会话被中断
今天在登录公司内部的服务器的时候,无法进行远程访问. 弹出错误信息:没有远程桌面授权服务器可以提供许可证,远程会话被中断 经过网上的寻找,原来是server 2012 远程登录只提供120天的使用期限 ...