近段時間做了一個項目,項目的前臺框架是基於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;
}
}
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>
<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技術可以生成靜態和動態的菜單,功能非常強大,但是對於小型的又常常需要數據庫的動態數據的需求,用這種方法不失爲一種便捷,高效的方法,希望能與大家共享。