考虑到应用系统会大量使用树形结构来表现数据,因此,提供一个通用树形标签供大家使用。
一、原始树形组件
关于树组件的实现有很多方式,此处使用著名的webfx-xtree实现,一个基于AJAX实现的树形菜单。它的原理就是每次都只加载当前结点下的所有结点,而对开发人员来说,就是只需要按一定的格式,生成一段XML代码。具体可参考http://webfx.eae.net/dhtml/xtree/index.html。
本文对树形组件做了一些别要的修改和扩充,修改后的树组件文末提供下载,解压后放在您的web文件夹common下面。
下文的重点是:通过提供一个jsp taglib,简化树结构的实现。
二、数据库设计
要实现数据的树形级别关系,在数据库设计中,某个数据实体(一条行记录),有且只有唯一的父实体元素与之对应即可。如机构表sysorg中,字段parentOrgId(可任意命名)为父机构ID,与机构本身的orgId构成树节点的父子关系。
通常,我们设置根节点的ID为“0”,这样,一级节点的父ID为“0”。
当节点ID无子节点(不是任何一个元素的父节点),此时此节点为最终节点,通常称之为叶节点(叶子)。
三、实体对象(VO)实现ITreeNode接口
ValueObject对象需要implements树节点接口com.basic.common.taglib.tree .ITreeNode。
分别实现如下三个方法:
//父节点ID
public String getParentId();
//节点ID
public String getNodeId();
//节点名
public String getNodeName();
四、实现ITreeService接口
一个任意的JAVA类,实现com.basic.common.taglib.tree.ITreeService的对象查找接口。
接口方法:
public List findAllRecords();
public ITreeNode findByNodeId(String nodeId);
实现该方法时候应注意:
1. 排除deleteFlag=’1’的记录。
2. 当结果集非常大,考虑到性能优化,可对结果集做缓存处理。(可暂不考虑实现,以后统一处理)。
五、注册树组件
在com.basic.common.taglib.tree.TreeUtil类中,维护treeMap静态变量,定义对应treeType的树名和ITreeService实现类。
六、在jsp中引入标签
<%@taglib uri="/WEB-INF/tag.tld" prefix="tag"%>
<tag:tree treeName="机构" root="<%=node%>" selectType="checkbox" selectAll="true" treeService="<%=orgService%>"/>
对各属性说明如下:
Attribute
|
Desc
|
Required
|
treeName
|
树名
|
true
|
root
|
展现的起始节点
如不指定,从根节点展示整个树形结构
|
false
|
selectType
|
选择方式
checkbox or radio
|
false
|
selectAll
|
勾选父节点时,自动选择所有子节点
只有当selectType为checkbox时该属性方生效
默认为false
|
false
|
checkedId
|
标识哪些节点被选中
内容为以“ ,”分隔的nodeId串
|
false
|
treeService
|
ITreeService接口的实现类实例
|
true
|
treeSql
|
直接构造树形sql
|
false
|
lazy
|
是否延迟加载
就是在点击某节点的时候,才load子节点
|
false
|
selectParent
|
对checkbox或者radio而言
当选择的子,是否自动勾选对应的所有的父
|
False
|
1. 点击某一个节点时,触发函数selectNode()。
atree.getSelected()返回当前点击的节点对象node,node.value和node.text为对应的节点ID和节点名。
自行在javascript中重写selectNode函数。
2. 当使用勾选时,atree.getSelectedChildNodes()返回当前勾选的节点集合。
3. 在页面中双击鼠标左键(ondblclick)时,会自动展开或收缩当前树。
七、直接使用SQL语句构造树
实现ITreeService和ItreeNode接口来构造树,相对有点麻烦。
利用SqlTreeService可以直接通过sql语句来构造树,以机构为例,该SQL语句写法如下:
select orgid as nodeid,orgname as nodename,parentorgid as parentid from sysorg where deleteflag='0'
请注意红色字符的写法。
对某些实体,没有对应的父ID,parentid的构造语句为:‘0’as parentid
这时,标签的引用变为:
<hnisi:tree treeName="×××" treeService="<%=new SqlTreeService("your sql")%>"/>
八、在javascript中引用树选择对话框
1、 在jsp中引入JS文件:
<script src="<%=request.getContextPath()%>/js/COMMON.js"></script>
2、 在javascript中,定义要引用的Tree对象
3、 Tree对象有如下属性:
this.treeType = null;//树类型 sysorg 。。。
this.rootId = null;//树根
this.checkedId = null;//选中的节点ID,“,”分隔
this.selectType = null;//checkbox or radio
this.selectAll = null;//是否自动选择所有子节点
this.width = null;//对话框的宽度
this.height = null;//对话框的高度
this.params = null;//附加参数值,用于TreeService的构造函数
this.sql = null;//根据特定sql语句直接构造树
this.treeName = null;//树显示名
其中treeType和sql至少设置一个,分别代表两种的典型构造树的方式:一种属性实现ITreeService和ItreeNode两个接口,然后在TreeUtil.java中注册树组件,比较清晰,可以灵活的做一些复杂处理,但稍嫌复杂;另一种是直接传递SQL语句构造树组件,使用起来比较简单,无需实现相关结构,无需注册树组件,但灵活性相对欠缺。
获取树选择器的返回值,可直接调用COMMON.Js的getValues(tree)方法,返回数组Array,Array[0]为逗号分隔的ID串,Array[1]为逗号分隔的NAME串。
九、文件下载和部署
1、 修改后的webfx-xtree组件,下载,解压后放于your web/common目录下。
2、 Java source,下载。
3、 在web.xml中部署一个servlet,用来生成tree xml
<servlet>
<servlet-name>treexml</servlet-name>
<servlet-class>
com.basic.common.taglib.tree.TreeXmlServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>treexml</servlet-name>
<url-pattern>/treexml</url-pattern>
</servlet-mapping>
|