目的 通过配置文件himenu-config.xml动态装配树型结构,要求不对V端(JSP或Javascript)不做任何修改,树的深度—深度包括两层含义1组件与组件之间的关联层次的深度2树本身的层次的深层—不做任何限制,动态—动态也包括两层含义1树本身的数据是动态的均应从数据库中调用2动态加载即只有点击当前层的节点时才去加载当前层的下一层数据—构建,多语言的支持要求可配置—从数据库取出的数据可以是直接显示的也可是资源文件中的键值以支持多语言。最终的目的就是通过配置而不用写任何代码来实现树型结构的自动渲染。
资源 参考资源1.struts-menu 2.Xtree 3.XLoadTree 4.XMLDcoder
规则 一个组件只能有0-1个父组件,一组件只能有0-2个子组,也可自描述即,一个组件可以是它自已的父组件
原理 当调用action时要带入至少一个参数如下面这样的一个URL 有两个参数menuName为配置文件中菜单的名称type为重定向的位向返回的字符串,其中nenuName参数是必须填写的,具体配置参见/WEB-INF/config/hi.xml配置文档tree.action
?menuName=menuName(himenu-config.xml)&type=nextforwardName通过配置。 WebDynamicTreeManager treemgr=new
WebDynamicTreeManager(); //创建动态树管理器
request.setAttribute("com.hi.tree.menu",treemgr.getMenu(request.getParameter("menuName"),parMap,contain)); //treemgr.getMenu()方法得到动态树的HiMenuComponet对象
; treemgr. getLoadMenu()方法为动态加载的HiMenuComponet对象注意该方法只构建一层HiMenuComponet对象,每次都是动态加载下一层数据。返回的JSP页面主要的代码为
<menu:useMenuDisplayer name="Velocity"
config="/templates/xtree.html"
//指定要处理当前模板的显示类bundle="org.apache.struts.action.MESSAGE">
if (document.getElementById) {
<hi:displayMenu
name="com.hi.tree.menu"/> //将HiMenuComponet对象按显示类对象的约束画出来
内部运行机制参见API。
菜单配置:
keymap
|
用于存储父子关系的值(注:该属性只对动态树有效)
|
parent
|
当前菜单作为父菜单的POJO属性名
|
child
|
当前菜单作为子菜单的POJO属性名
|
childValue
|
查询子菜单时初始缺省值
|
menuName
|
菜单名称与key值应保持一致
|
beanName
|
对应数据库对象的javaBean类的全限定名
|
submenuName
|
当前菜单所有的子菜单名称,最多只能包含两个子菜单,以逗号分隔
|
title
|
作为树根显示的文字
|
titleField
|
各节点显示文字的字段名
|
needShow
|
是否显示,可以作为激活条件
|
sort
|
当前层上所有节点的排列顺序,对应数据库对象中的字段名
|
action
|
当前节点的动作,分3种策略
|
{js}
|
标记执行javascript代码
|
{url}
|
标记链接动作
|
{property}
|
.对存储于数据库中字段的值的读取;数据库中可以存储链接{url}XXX,{js}XXXX等,可以再次解析执行
|
javascript
|
定义通过{js}指定的要执行的js函数
|
bundle
|
如果标题显示要支持多语言,要加上对应的资源文件的路径与文件名
|
target
|
如果有多个frame可以指定action功能后的目标
|
checkbox
|
如果需要显示复选框就为true
|
iconmap
|
如果节点右侧还要求多加几个图标及与图标对应的action
|
leafMethod
|
在使用延时加载树时要配置,注意只有在动态树中配置才有效,且该属性的值应是对应POJO下的一个无参方法并且返回类型与boolean
|
cache
|
树所描述的数据库是否加入缓存,注意加入缓冲区的数据将不会因数据的更新而更新,注意只有在静态树中配置有效
|
filter
|
对菜单树的数据进行过滤,提供两种接口方式对数据进行过滤
MenuFilterProcessor 在获取数据之前填加过滤器
MenuCollectionProcessor 在获取数据之后再对数据做整理
动态数据参数通过url传递:tree.action**&id=2
|
动态树访问配置
|
loadTree.action?menuName=agentTree
|
静态加载的url配置
|
tree.action?menuName=agentTree
|
提示:所有的配置信息必须写在WEB-INF/config/himenu-config.xml文件中。该文件实际上是在描述一个HashMap,每个key对应的都是一个菜单名、value对应着
com.hi.tools.tree.WebDynamicMenuDefine类的实例,该类只是一个简单的javaBean,装载对菜单树的配置信息
注意其中agentTree是在/WEB-INF/config/himenu-config.xml 配置的树配置
|
[#id]
|
其中的id是bean的属性名用“[# ]”封起来表示取其相应的值
|
|
|
|
|
|
1.执行javascript:使用{js}来标记实例代码:<void property="action">
<string>{js}backAgent([#id],"'[#orgName]"');</string> //[#id]动态取出bean属性为id的值,
// backAgent是在点击树形链接要执行的js函数名
</void>
javascript定义通过{js}指定的要执行的js函数
<void property="javascript">
<string>
function
backAgent (id,orgName){
opener.document.getElementById('agent.parentOrgName').value=orgName;
opener.document.getElementById('agent.id').value=id;
window.close();
}
</string>
</void>
2.链接:<void property="action">
<string>{url}test.action?id=[#id]&name=[#name]</string>
//在点击树形链接时会请求test.action并且动态带回id和name的值
3.对存储于数据库中字段的值的读取:<void property="action"><string>{property}link
</string> //link是数据库字段名非bean属性,即POJO的类名
iconmap 如果节点右侧还要求多加几个图标及与图标对应的action
<string>images/openfoldericon.png</string>
<string>commonEditAction.hi?bo=HiUser&recodeNum=[#himenuitemid]</string>
<void property="leafMethod">
<string>getLeaf</string>//getLeaf是pojo类中检查但前节点是不是页节点的方法名主要用于动态数
</void>
<void property="cache">
<boolean>true</boolean>
</void>
<void property="filter">
<string>demo.tree.AuthUserGroupCollProcessor</string>
</void>
代码文件 /WEB-INF/menu-config.xml struts-menu本身的配置文件
/WEB-INF/config/himenu-config.xml 所有树的配置文件
com.hi.tools.tree.WebDynamicMenuDefine.java
与配置文件中单个菜单对应的javaBean
com.hi.tools.tree.
HiMenuComponent.java 树组件文件
com.hi.tools.tree.
WebDynamicTreeManager.java 动态加载树组件
/common/commonTree.jsp
通用树显示页面
/common/commonLoadTree.jsp
通用动态加载树显示页面
/common/subMenu.jsp 当动态加载树点击某节点时调用的JSP文件,该文件最终组成一个XLoadTree支持的xml文件
/templates/xtree.html 显示树的模板文件
/templates/xloadtree.html 显示动态加载树的模板文件
/templates/xloadsub.html 当动态加载树点击某节点时的模板文件 ;模板文件均由JSP文件中的标签调用
/scripts/xtree.js; /scripts/xloadtree.js; /scripts/xmextras.js 均为将数据转换为html字符打印并显示出来
配置文档详解
<void method="put">
<string>agentTree</string>
<object class="org.hi.base.menu.strutsmenu.WebDynamicMenuDefine"><!--配置树对应的类实例 -->
<void property="keymap"><!--配置父子关系-->
<object class="java.util.HashMap"> s
<void method="put">
<string>id</string>
<string>parentOrg</string>
</void><!--id和parentOrg都beanName对应的bean的属性名-->
</object>
</void>
<void property="parent">
<string>id</string>
</void>
<void property="child">
<string>parentOrg</string>
</void><!--parent和child指定父子关系-->
<void property="childValue">
<string>0</string>
</void>
<void property="menuName"><!--配置树名-->
<string>agentTree</string>
</void>
<void property="beanName"><!--配置要形成树的bean -->
<string>com.cltc.maotai.agent.model.Agent</string>
</void>
<void property="submenuName"><!--扩展节点的数名-->
<string>agentTree</string>
</void>
<void property="title">
<string>代理</string><!--跟节点的名称-->
</void>
<void property="titleField">
<string>orgName</string><!--显示文字的字段名-->
</void>
<void property="needShow">
<boolean>true</boolean><!--是否显示-->
</void>
<void property="cache"><!--定义在静态树的中是否使用缓存-->
<boolean>true</boolean>
</void>
<void property="javascript"><!--定义{js}标记的要执行的js函数-->
<string>
function
backAgent(id,orgName){
opener.document.getElementById('agent.parentOrgName').value=orgName;
opener.document.getElementById('agent.parentOrg.id').value=id;
window.close();
}
</string>
</void>
<void property="iconmap"><!--树的节点链接后面使用图标-->
<object class="java.util.HashMap">
<void method="put">
<string>images/b2xwhite.gif</string>
<string>{js}backAgent([#id],"'[#orgName]"');</string>
</void><!--如果函数中的参数是字符串必须写成"'[#orgName]"'这样的格式orgName是bean属性名,注意在方法参数中如果是字符串则要通过"’做转义,并且只能用单引号 -->
</object>
</void>
<void property="action"><!--菜单节点上所要执行的动作可以是URL也可是js的方法-->
<string>{url}agentEdit.action?id=[#id]</string>
</void>
<void property="checkbox"><!--定义是否在树中使用复选框,页面配套调用函数selectedcb() -->
<boolean>true</boolean>
</void>
<void property="leafMethod">
<string>getLeaf</string>
</void><!--配置动态树中检验是不是页节点的函数,此函数定义在beanName指定的bean中,目的是检测该节点还有没有子结点-->
</object>
</void>