考虑到应用系统会大量使用树形结构来表现数据,因此,提供一个通用树形标签供大家使用。

一、原始树形组件

关于树组件的实现有很多方式,此处使用著名的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

勾选父节点时,自动选择所有子节点

只有当selectTypecheckbox时该属性方生效 

默认为false

false

checkedId

标识哪些节点被选中

内容为以“ ,”分隔的nodeId

false

treeService

ITreeService接口的实现类实例

true

treeSql

直接构造树形sql

false

lazy

是否延迟加载

就是在点击某节点的时候,才load子节点

false

selectParent

checkbox或者radio而言

当选择的子,是否自动勾选对应的所有的父

False

1. 点击某一个节点时,触发函数selectNode()

       atree.getSelected()返回当前点击的节点对象nodenode.valuenode.text为对应的节点ID和节点名。

       自行在javascript中重写selectNode函数。

2. 当使用勾选时,atree.getSelectedChildNodes()返回当前勾选的节点集合。

3. 在页面中双击鼠标左键(ondblclick)时,会自动展开或收缩当前树。

七、直接使用SQL语句构造树

       实现ITreeServiceItreeNode接口来构造树,相对有点麻烦。

       利用SqlTreeService可以直接通过sql语句来构造树,以机构为例,该SQL语句写法如下:

       select orgid as nodeid,orgname as nodename,parentorgid as parentid from sysorg where deleteflag='0'  
      请注意红色字符的写法。

       对某些实体,没有对应的父IDparentid的构造语句为:0as 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;//树显示名  

    其中treeTypesql至少设置一个,分别代表两种的典型构造树的方式:一种属性实现ITreeServiceItreeNode两个接口,然后在TreeUtil.java中注册树组件,比较清晰,可以灵活的做一些复杂处理,但稍嫌复杂;另一种是直接传递SQL语句构造树组件,使用起来比较简单,无需实现相关结构,无需注册树组件,但灵活性相对欠缺。

   

    获取树选择器的返回值,可直接调用COMMON.JsgetValues(tree)方法,返回数组ArrayArray[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>