递归算法在树型菜单中的应用
2006-09-26 11:57
204 查看
近段时间做了一个项目,项目的前台框架是基于webwork+freemarker。需要一个树型菜单,于是研究了一下树型菜单的编写方法,发现大多数树型菜单都是利用xml通过javascript生成的,对于dom不太熟悉的开发这来说,显得太复杂,而且层次感不强。 我们项目采用的是另外一种方法,把菜单的动态生成的所有工作交给业务类处理,然后处理,返回一个html代码以字符串的形式给界面(freemarker),前台只需调用即可以了,这样做的一个最大的好处就是菜单动态数据的生成是在java编译阶段生成,而且只需要生成一次,即保存在内存中,这样就减少了界面重复查询数据的负担,项目运行结果发现菜单运行的效率非常高,一下是它实现核心代码:
package com.sunrise.baselib.action.home;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import com.opensymphony.xwork.ActionContext;
import com.opensymphony.xwork.ActionSupport;
import com.sunrise.baselib.domain.FunctionView;
import com.sunrise.baselib.domain.ProductView;
import com.sunrise.baselib.domain.TechView;
import com.sunrise.baselib.service.KnowledgeQueryService;
public class LoadKnowledgeSortAction extends ActionSupport ...{
List products;
//service操纵数据库
KnowledgeQueryService knowledgeQueryService;
//设置产品视图的菜单
public String setProductMenu(String choose) throws SQLException ...{
List list;
String modulename = "";
String moduleid = "";
String source = "";
String sql = "from ProductView f where f.parentProduct is null Order by f.name";
list = this.knowledgeQueryService.find(sql);
if (list.size() > 0) ...{
Iterator it = list.iterator();
while (it.hasNext()) ...{
ProductView produc = (ProductView) it.next();
if (produc.getProductViews().size() > 0) ...{
source = source
+ "<li nowrap>"
+ "<a href='#'>+</a>"
+"<td><input type='checkbox' name='product"+produc.getId().toString()+"'></td>"
+produc.getName() + "("
+ produc.getProductViews().size() + ")</li>";
} else ...{
source = source
+ "<li nowrap>"
+"<a href='#'></a>"
+"<td><input type='checkbox' name='product"+produc.getId().toString()+"'></td>"
+ produc.getName() + "</li>";
}
if (produc.getProductViews().size() > 0) ...{
source = source + getProductSource(produc,choose);
}
}
}
System.out.println(source);
return source;
}
//导入字节点的数据
private String getProductSource(ProductView produc,String choose) throws SQLException ...{
String modulename = "";
String moduleid = "";
String source = "";
String rowsex = "";
modulename = produc.getName();
moduleid = produc.getId() + "";
Iterator itx = produc.getProductViews().iterator();
while (itx.hasNext()) ...{
ProductView producx = (ProductView) itx.next();
if (producx.getProductViews().size() > 0) ...{
source = source + "<li nowrap>"
+ "<a href='#'>+</a>"
+"<td><input type='checkbox' +
+name='product"+producx.getId().toString()+"'></td>"
+producx.getName() + "("
+ producx.getProductViews().size() + ")</li>";
} else ...{
source = source
+ "<li nowrap>"
+"<a href='#'></a>"
+"<td><input type='checkbox' name='product"+producx.getId().toString()+"'></td>"
+ producx.getName() + "</li>";
}
if (producx.getProductViews().size() > 0) ...{
//递归调用
source = source + getProductSource(producx,choose);
}
}
source = "<ul>" + source + "</ul>";
return source;
}
//导出product列表,放在session中,用于界面调用
public String loadProducts() throws Exception...{
this.products=this.knowledgeQueryService.findProducts();
//调用setProductMenu()生成html字符串
String module = this.setProductMenu("module");
ActionContext ctx = ActionContext.getContext();
Map session = ctx.getSession();
session.put("productList", module);
return SUCCESS;
}
public List getProducts() ...{
return products;
}
public KnowledgeQueryService getKnowledgeQueryService() ...{
return knowledgeQueryService;
}
public void setKnowledgeQueryService(KnowledgeQueryService knowledgeQueryService) ...{
this.knowledgeQueryService = knowledgeQueryService;
}
}
界面调用的代码就简单的不能再简单了:
<link rel="stylesheet" href="../css/aqtree3clickable.css">
<script type="text/javascript" src="../js/aqtree3clickable.js"></script>
<script language="javascript">...
<#------ 提交时检查是否选择至少一项 ------>
function verifyValue()
...{
var product_num=0;
var product_id_list="";
var product_name_list="";
<#list products as product>
if(document.all.product$...{product.id}.checked)
...{
if(product_num>0)...{
product_name_list+=",";
product_id_list+=",";
}
product_id_list+=$...{product.id};
product_name_list+="${product.name}";
product_num++;
}
</#list>
if(product_num==0)
...{
alert("你没有选择任何记录,请选择! ---否则请点击'关闭'---");
return false;
}
else
...{
window.opener.document.all("products").value=product_id_list;
window.opener.document.all("products_name").value=product_name_list;
self.close();
}
}
<#------------- 全选的功能实现 ------------->
function selectAll(current_form)
...{
var current_state=current_form.configure_check.checked;
<#list products as product>
if(current_state)
current_form.product$...{product.id}.checked=true;
else
current_form.product$...{product.id}.checked=false;
</#list>
return true;
}
function cancel()...{
self.close();
}
</script>
<body>
<div class="div">
<table width="100%" border="0" align="center" cellpadding="0" cellspacing="1">
<tr>
<td nowrap> [产品列表]</td>
<td>
</td>
</tr>
</table>
<form name="frmList" id="frmList" method="post" action="" onsubmit="return verifyValue();">
<#-- 菜单的实现 -->
<ul class="aqtree3clickable">
<li><input type="checkbox" name="configure_check" onClick="selectAll(this.form)"><a href="#">全部产品</a></li>
<ul>
<#-- 菜单实现 -->
${Session["productList"]?if_exists}
</ul>
</ul>
<TABLE id="submittable" cellSpacing="1" cellPadding="0" width="99%" align="center" bgColor="#b1b1b1" border="0" Sortable="true" nameColNum="2" idColNums="1" SetRowNumber="true" MoveColable="false" showStatus="true" Editable="false">
<tr class="content_tab_data">
<td><input type="submit" name="submit" value="提交" onClick="verifyValue()">
<input type="button" name="cancel" value="关闭" onClick="self.close()"></td>
</tr>
</TABLE>
</div>
</form>
form标签里面的东东就是生成菜单的地方,只需要一句话${Session["productList"]?if_exists} ,呵呵,是不是很简单呀?
我的体会是xml技术可以生成静态和动态的菜单,功能非常强大,但是对于小型的又常常需要数据库的动态数据的需求,用这种方法不失为一种便捷,高效的方法,希望能与大家共享。
package com.sunrise.baselib.action.home;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import com.opensymphony.xwork.ActionContext;
import com.opensymphony.xwork.ActionSupport;
import com.sunrise.baselib.domain.FunctionView;
import com.sunrise.baselib.domain.ProductView;
import com.sunrise.baselib.domain.TechView;
import com.sunrise.baselib.service.KnowledgeQueryService;
public class LoadKnowledgeSortAction extends ActionSupport ...{
List products;
//service操纵数据库
KnowledgeQueryService knowledgeQueryService;
//设置产品视图的菜单
public String setProductMenu(String choose) throws SQLException ...{
List list;
String modulename = "";
String moduleid = "";
String source = "";
String sql = "from ProductView f where f.parentProduct is null Order by f.name";
list = this.knowledgeQueryService.find(sql);
if (list.size() > 0) ...{
Iterator it = list.iterator();
while (it.hasNext()) ...{
ProductView produc = (ProductView) it.next();
if (produc.getProductViews().size() > 0) ...{
source = source
+ "<li nowrap>"
+ "<a href='#'>+</a>"
+"<td><input type='checkbox' name='product"+produc.getId().toString()+"'></td>"
+produc.getName() + "("
+ produc.getProductViews().size() + ")</li>";
} else ...{
source = source
+ "<li nowrap>"
+"<a href='#'></a>"
+"<td><input type='checkbox' name='product"+produc.getId().toString()+"'></td>"
+ produc.getName() + "</li>";
}
if (produc.getProductViews().size() > 0) ...{
source = source + getProductSource(produc,choose);
}
}
}
System.out.println(source);
return source;
}
//导入字节点的数据
private String getProductSource(ProductView produc,String choose) throws SQLException ...{
String modulename = "";
String moduleid = "";
String source = "";
String rowsex = "";
modulename = produc.getName();
moduleid = produc.getId() + "";
Iterator itx = produc.getProductViews().iterator();
while (itx.hasNext()) ...{
ProductView producx = (ProductView) itx.next();
if (producx.getProductViews().size() > 0) ...{
source = source + "<li nowrap>"
+ "<a href='#'>+</a>"
+"<td><input type='checkbox' +
+name='product"+producx.getId().toString()+"'></td>"
+producx.getName() + "("
+ producx.getProductViews().size() + ")</li>";
} else ...{
source = source
+ "<li nowrap>"
+"<a href='#'></a>"
+"<td><input type='checkbox' name='product"+producx.getId().toString()+"'></td>"
+ producx.getName() + "</li>";
}
if (producx.getProductViews().size() > 0) ...{
//递归调用
source = source + getProductSource(producx,choose);
}
}
source = "<ul>" + source + "</ul>";
return source;
}
//导出product列表,放在session中,用于界面调用
public String loadProducts() throws Exception...{
this.products=this.knowledgeQueryService.findProducts();
//调用setProductMenu()生成html字符串
String module = this.setProductMenu("module");
ActionContext ctx = ActionContext.getContext();
Map session = ctx.getSession();
session.put("productList", module);
return SUCCESS;
}
public List getProducts() ...{
return products;
}
public KnowledgeQueryService getKnowledgeQueryService() ...{
return knowledgeQueryService;
}
public void setKnowledgeQueryService(KnowledgeQueryService knowledgeQueryService) ...{
this.knowledgeQueryService = knowledgeQueryService;
}
}
界面调用的代码就简单的不能再简单了:
<link rel="stylesheet" href="../css/aqtree3clickable.css">
<script type="text/javascript" src="../js/aqtree3clickable.js"></script>
<script language="javascript">...
<#------ 提交时检查是否选择至少一项 ------>
function verifyValue()
...{
var product_num=0;
var product_id_list="";
var product_name_list="";
<#list products as product>
if(document.all.product$...{product.id}.checked)
...{
if(product_num>0)...{
product_name_list+=",";
product_id_list+=",";
}
product_id_list+=$...{product.id};
product_name_list+="${product.name}";
product_num++;
}
</#list>
if(product_num==0)
...{
alert("你没有选择任何记录,请选择! ---否则请点击'关闭'---");
return false;
}
else
...{
window.opener.document.all("products").value=product_id_list;
window.opener.document.all("products_name").value=product_name_list;
self.close();
}
}
<#------------- 全选的功能实现 ------------->
function selectAll(current_form)
...{
var current_state=current_form.configure_check.checked;
<#list products as product>
if(current_state)
current_form.product$...{product.id}.checked=true;
else
current_form.product$...{product.id}.checked=false;
</#list>
return true;
}
function cancel()...{
self.close();
}
</script>
<body>
<div class="div">
<table width="100%" border="0" align="center" cellpadding="0" cellspacing="1">
<tr>
<td nowrap> [产品列表]</td>
<td>
</td>
</tr>
</table>
<form name="frmList" id="frmList" method="post" action="" onsubmit="return verifyValue();">
<#-- 菜单的实现 -->
<ul class="aqtree3clickable">
<li><input type="checkbox" name="configure_check" onClick="selectAll(this.form)"><a href="#">全部产品</a></li>
<ul>
<#-- 菜单实现 -->
${Session["productList"]?if_exists}
</ul>
</ul>
<TABLE id="submittable" cellSpacing="1" cellPadding="0" width="99%" align="center" bgColor="#b1b1b1" border="0" Sortable="true" nameColNum="2" idColNums="1" SetRowNumber="true" MoveColable="false" showStatus="true" Editable="false">
<tr class="content_tab_data">
<td><input type="submit" name="submit" value="提交" onClick="verifyValue()">
<input type="button" name="cancel" value="关闭" onClick="self.close()"></td>
</tr>
</TABLE>
</div>
</form>
form标签里面的东东就是生成菜单的地方,只需要一句话${Session["productList"]?if_exists} ,呵呵,是不是很简单呀?
我的体会是xml技术可以生成静态和动态的菜单,功能非常强大,但是对于小型的又常常需要数据库的动态数据的需求,用这种方法不失为一种便捷,高效的方法,希望能与大家共享。
相关文章推荐
- 递归算法实现树型菜单
- asp.net MVC&JQuery 应用(树型菜单 )
- 侧划菜单的应用
- 原创:由XML文档创建树型菜单类
- 1.窗体与界面设计-菜单应用实例
- 2.2 修改应用模块名称(Menu菜单)
- 用PHP实现windows资源管理器风格的树型菜单
- 把VBS应用到文件(夹)右键菜单中
- DTree生成漂亮的动态树型菜单
- (一)实际项目中树形数据结构与递归算法应用
- (一)实际项目中树形数据结构与递归算法应用
- asp.net MVC&JQuery 应用(树型表格 )
- 递归算法应用值判断字符串是否为回文
- Delphi 中 CoolBar 和 ToolBar、菜单的集成应用
- javaFx菜单简单应用示例--1多级菜单
- 如何应用ul、li标签 创建css横向导航菜单?
- DIV+CSS构成的树型菜单符合web标准
- oracle中的树型递归的应用
- 【Android 应用开发】 ActionBar 样式详解 -- 样式 主题 简介 Actionbar 的 icon logo 标题 菜单样式...
- js控制树型菜单