递归算法在树型菜单中的应用

近段时间做了一个项目,项目的前台框架是基于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>&nbsp;&nbsp;[产品列表]</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)"><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技术可以生成静态和动态的菜单,功能非常强大,但是对于小型的又常常需要数据库的动态数据的需求,用这种方法不失为一种便捷,高效的方法,希望能与大家共享。
 
  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jimmy_developing

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值