当前位置: 代码迷 >> Web前端 >> s2sh+freemarker+jquery+jquery-treeview 无限级树形菜单受权
  详细解决方案

s2sh+freemarker+jquery+jquery-treeview 无限级树形菜单受权

热度:1153   发布时间:2012-11-09 10:18:48.0
s2sh+freemarker+jquery+jquery-treeview 无限级树形菜单授权
  先上效果图 


  首先说说jquery-treeview 这个插件,这里有官方的demo http://jquery.bassistance.de/treeview/demo/     用法很简单
我们只需要组织好相应的html标签就好了,例如:
<div id="treeContainer">
 <ul>
    <li>父节点
      <ul>
           <li>子节点1</li>
           <li>子节点2</li>
      </ul>
     </li>
 </ul>
</div>


然后简单的调用   $("#treeContainer ul").Treeview();  就能生成一颗js树

那么接下来,我们就要想办法来组织这些标签,我自己是在后台使用freemarker来动态生成的。
至于系统栏目表的结构,就是一个引用自身的表,
例如 t_menu表有字段 id name parent 这三个字段
那么相应的数据有可能是这样的
id   name      parentId
1    系统管理       0(或者NULL)
2    系统日志       1
3    用户管理       1
4    文章管理       0(或者NULL)
5    文章分类       4

这个大家应该一看就知道是一个无限级树形结构.
那么使用hibernate后,我们首选需要查询出所有的顶级菜单和相应的子菜单列表
hql = "from t_menu where parentId = 0"
由于hibernate可以级联查询出所有子菜单的数据,所以,我们可以很方便的拿到一个list,它的数量为2(2个顶级菜单)

然后把这个list对象传给freemarker的上下文,就可以用freemarker的宏来递归产生html标签(我上面的例子和对象只是简单举例,下面的模板内容是我实际项目的编码,所以看起来会和上面举的例子的不一致,不过过程都一样的,理解了都一样的,就是迭代菜单名,然后判断是否还有子菜单,有就递归调用宏.)

<#-- 定义宏buildCheckbox -->
<#macro buildCheckbox purviewItem>
		  <#if purviewItem= 1>
		         &nbsp;<input type="checkbox" name="purview" value ="1" >查看
		  <#elseif purviewItem = 2>
		         &nbsp;<input type="checkbox" name="purview" value ="2" >添加
		  <#elseif purviewItem = 3>
		         &nbsp;<input type="checkbox" name="purview" value ="3" >修改
		  <#elseif purviewItem = 4>
		         &nbsp;<input type="checkbox" name="purview" value ="4" >删除
		</#if>
</#macro> 

<#-- 定义宏buildNode -->
<#macro buildNode child parent>
    <li id="${parent.MPkid}" parentId="${parent.MParentId}">${parent.MItem}
      <#if child?? && child?size gt 0> 
           <ul>
             <#list child as t> 
                 <#-- 递归调用宏buildNode -->
                 <@buildNode child=t.children parent=t/>
             </#list> 
           </ul>
           <#else>
             <#-- 如果是叶子节点 -->
              <#list parent.options as purviewItem>
                   <#-- 循环调用宏buildCheckbox -->
                   <@buildCheckbox purviewItem=purviewItem/>
              </#list>
             <#-- &nbsp;<input type="checkbox" name="purview" value ="1" >查看&nbsp;&nbsp;<input type="checkbox" name="purview" value ="2" >添加&nbsp;&nbsp;<input type="checkbox" name="purview" value ="3" >修改&nbsp;&nbsp;<input type="checkbox" name="purview" value ="4" >删除-->
      </#if>
    </li>
</#macro> 
<ul>
<#list rootMenus as root>
   <#-- 循环调用宏buildNode -->
    <@buildNode child=root.children parent=root/>
</#list>
</ul>





就这样,就能够产生一个无限级树的js菜单所需要的html标签了,接着只需要在页面简单的调用   $("#treeContainer ul").Treeview(); 就好了.


另一方面,至于如何授权(遍历js树),就有很多方法了,我是这么实现的
工具:用到json2.js和google gson这个库来将json对象转换成java对象

页面代码,遍历树,组织json对象,用于提交到服务器
//定义rolePurview对象
 var rolePurview = function(jewelryRole, jewelryMenu, opQuery){  
  this.jewelryRole = jewelryRole;
  this.jewelryMenu = jewelryMenu;
  this.opQuery = opQuery;
 } 
 
  //定义集合对象,用于递归时地址传递  
  var rolePurviews = {str: '{ "rolePurviews":['};
 
  //授权
  function save(){
	 //迭代所有根节点
	 $("li[parentId='0']").each(function(){
	    var $this = $(this);
	    var menu = $this.attr('id');
	    var options = [];
	    //判断根目录下的所有叶子节点是否有进行选择的,有就进行递归遍历
	    if($this.find("input:checked").length > 0){
		  recursiveTree($this,rolePurviews);
	    }
 	  });
 	  //如果所有checkbox都没有选择
 	  if(rolePurviews.str.length == 18){
           rolePurviews.str += ',';
   	  }
 	  rolePurviews.str = rolePurviews.str.substring(0,rolePurviews.str.length-1)+"]}";
	  //alert(rolePurviews.str);
	  roleServiceDWR.roleAuthorizationDwr(purview,operations[1],role,rolePurviews.str,{
        callback:function(data){
                if(data == 0){
		            sucInfoHandler("角色授权成功!",back);
		        }else{
		            sucInfoHandler("角色授权失败!",emptyPurviews);
		        }
         }
      });
   }
 
 //递归遍历js树
 function recursiveTree(node,rolePurviews){
		 var options = [];
		 var sdataObj;
		 var jsonText;
		 var nodeId = node.attr('id');
		 //如果不是叶子节点,且其下的叶子节点有被选择的.
		 if(node.find("ul").length > 0 && node.find("input:checked").length > 0){
			  sdataObj = new rolePurview(role,nodeId,options);
			  jsonText = JSON.stringify(sdataObj);
			  rolePurviews.str+=jsonText+",";
			  node.find("li[parentId="+nodeId+"]").each(function(){
			  	//递归
				return recursiveTree($(this),rolePurviews);
			  })
		 }else if(node.find("ul").length == 0 && node.find("input:checked").length > 0){
			  //如果是叶子节点,且有被选择的
			  node.find("input:checked").each(function(){
				options.push($(this).val());
			  })
			  sdataObj = new rolePurview(role,nodeId,options);
			  jsonText = JSON.stringify(sdataObj);
			  rolePurviews.str+=jsonText+",";
		 }
    } 




然后 服务器里,只需要简单的调用google gson的反射方法,就能够拿到一个list对象,里面装好了每个栏目的相应权限.
Gson gson = new Gson();
ListRolePurview r = gson.fromJson(jsonStr, ListRolePurview.class);
1 楼 jjxboy 2010-09-06  
能不能给个源码啊,谢谢了!
jack(a)win-liutan.com
2 楼 jjxboy 2010-09-14  
你是我看得云里雾里的,能不能给个完整一点的demo看看啊?谢谢了!
3 楼 chenxiang105 2010-09-25  
给个源码崇拜下.....win.sb@hotmail.com
4 楼 ┿┅мīSS 2010-10-22  
chenxiang105 写道
给个源码崇拜下.....win.sb@hotmail.com

已发送.
5 楼 ┿┅мīSS 2010-10-22  
jjxboy 写道
能不能给个源码啊,谢谢了!
jack(a)win-liutan.com

已发送
6 楼 kangmint74 2010-12-28  
给个完整源码吧 815697415@qq.com 谢谢
7 楼 用手踢球 2011-03-24  
能不能给个源码?
  相关解决方案