用ExtJS 实现动态载入树(Load tree)
1、 数据库背景:这里有一个组织机构表,结构如下:
<shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"></path><lock v:ext="edit" aspectratio="t"></lock></shapetype><shape id="图片_x0020_2" style="VISIBILITY: visible; WIDTH: 4in; HEIGHT: 148.5pt; mso-wrap-style: square" o:spid="_x0000_i1025" type="#_x0000_t75"><imagedata src="file:///C:/DOCUME~1/myloon/LOCALS~1/Temp/msohtmlclip1/01/clip_image001.png" o:title="" croptop="13843f" cropbottom="35747f" cropleft="22338f" cropright="23858f"></imagedata></shape>
Oracle DDL脚本 :
create table ORGANIZATION(
ORGID NUMBER(10) not null,
PARENTID NUMBER(10) not null,
ORGNAME VARCHAR2(32) not null,
ISAVAILABLE NUMBER(1) default 1 not null
);
alter table ORGANIZATION
add constraint PK_ORGID primary key (ORGID);
alter table ORGANIZATION
add constraint FK_ORGID_PARENTID foreign key (PARENTID)
references ORGANIZATION (ORGID);
初始化数据内容(注意第一行数据是必需的):
insert into LOON_ORGANIZATION (ORGID, PARENTID, ORGNAME, ISAVAILABLE) values (-100, -100, '组织机构图', 1);
insert into LOON_ORGANIZATION (ORGID, PARENTID, ORGNAME, ISAVAILABLE) values (1, -100, '公司总部1', 1);
insert into LOON_ORGANIZATION (ORGID, PARENTID, ORGNAME, ISAVAILABLE) values (2, -100, '公司总部2', 1);
insert into LOON_ORGANIZATION (ORGID, PARENTID, ORGNAME, ISAVAILABLE) values (3, -100, '公司总部3', 1);
insert into LOON_ORGANIZATION (ORGID, PARENTID, ORGNAME, ISAVAILABLE) values (4, 1, '公司总部1-1', 1);
insert into LOON_ORGANIZATION (ORGID, PARENTID, ORGNAME, ISAVAILABLE) values (5, 1, '公司总部1-2', 1);
insert into LOON_ORGANIZATION (ORGID, PARENTID, ORGNAME, ISAVAILABLE) values (6, 2, '公司总部2-1', 1);
insert into LOON_ORGANIZATION (ORGID, PARENTID, ORGNAME, ISAVAILABLE) values (7, 2, '公司总部2-2', 1);
insert into LOON_ORGANIZATION (ORGID, PARENTID, ORGNAME, ISAVAILABLE) values (8, 3, '公司总部3-1', 1);
insert into LOON_ORGANIZATION (ORGID, PARENTID, ORGNAME, ISAVAILABLE) values (9, 3, '公司总部3-2', 1);
有了数据库支持就可以动态的从数据库中提取树数据。
第一步是建立JSP文件(org.jsp)和JavaScript(org.js)文件:
在org.jsp中导入ExtJS所必需的库文件,并在<body>中加入
<body>
<div id="tree-div" style="overflow:auto; height:300px;width:200px;border:2px solid #c3daf9;"></div>
</body>
Org.jsp文件完全可以是静态HTML文件,这里org.jsp中不包含任何动态内容,注意ExtJS所必需的库文件类库路径问题。
Org.js文件内容:
Ext.onReady(function() {
var Tree = Ext.tree;
var tree = new Tree.TreePanel( {
el : 'tree-div',//目标div容器
autoScroll : true,
animate : true,
enableDD : true,
containerScroll : true,
loader : new Tree.TreeLoader( {
dataUrl : ' OrgTreeJsonData.action '// OrgTreeJsonData.action就是要动态载入数据的请求地址,这里请求时会提交一个参数为node的值,值为root即new Tree.AsyncTreeNode()对象的id值
})
});
var root = new Tree.AsyncTreeNode( {
text : '组织机构树',
draggable : false,
id : '-100'//默认的node值:?node=-100
});
tree.setRootNode(root);
tree.render();
root.expand();
});
OrgTreeJsonData.action所请求的JSON数据例子:
[ {
"text" : "公司总部1",
"id" : "1",
"cls" : "folder"
}, {
"text" : "公司总部2",
"id" : "2",
"cls" : "folder"
}, {
"text" : "公司总部3",
"id" : "3",
"cls" : "folder"
}]
服务器端可以使用这样的SQL语句来查询:
select t.orgid,t.orgname,t.parentid from organization t
where t.parentid='-100' and t.orgid!='-100'
下面的代码片断用于struts2 action类中:
public String treeNode() {
try {
List<Object[]> list = this.organizationService.findByParentId(this.node);
if (list != null && !list.isEmpty()) {
boolean isFirst = true;
int i = 0;
int last = list.size();
for (Object[] o : list) {
if (i == 0) {
this.setJsonString("[{/"text/" :/"" + o[1].toString() + "/" ,/"id/" :/"" + o[0].toString()
+ "/" ,/"cls/" :/"folder/"} ");
} else if (i == (last - 1)) {
this.setJsonString(this.getJsonString() + ",{/"text/" :/"" + o[1].toString() + "/" ,/"id/" :/""
+ o[0].toString() + "/" ,/"cls/" :/"folder/"}]");
} else {
this.setJsonString(this.getJsonString() + ",{/"text/" :/"" + o[1].toString() + "/" ,/"id/" :/""
+ o[0].toString() + "/" ,/"cls/" :/"folder/"}");
}
i++;
}
} else {
this.setJsonString("");
}
System.out.println(this.getJsonString());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return this.INPUT;
}
return this.SUCCESS;
}
运行时的图:
<shape id="图片_x0020_5" style="MARGIN-TOP: 3.75pt; Z-INDEX: 1; VISIBILITY: visible; MARGIN-LEFT: -17.25pt; WIDTH: 198pt; POSITION: absolute; HEIGHT: 354.75pt; mso-wrap-style: square; mso-wrap-distance-left: 9pt; mso-wrap-distance-top: 0; mso-wrap-distance-right: 9pt; mso-wrap-distance-bottom: 0; mso-position-horizontal: absolute; mso-position-horizontal-relative: text; mso-position-vertical: absolute; mso-position-vertical-relative: text" o:spid="_x0000_s1027" type="#_x0000_t75"><imagedata src="file:///C:/DOCUME~1/myloon/LOCALS~1/Temp/msohtmlclip1/01/clip_image003.png" o:title="" cropbottom="29730f" cropright="53023f"></imagedata></shape><shape id="图片_x0020_8" style="MARGIN-TOP: 3.75pt; Z-INDEX: 2; VISIBILITY: visible; MARGIN-LEFT: 185.25pt; WIDTH: 189pt; POSITION: absolute; HEIGHT: 354pt; mso-wrap-style: square; mso-wrap-distance-left: 9pt; mso-wrap-distance-top: 0; mso-wrap-distance-right: 9pt; mso-wrap-distance-bottom: 0; mso-position-horizontal: absolute; mso-position-horizontal-relative: text; mso-position-vertical: absolute; mso-position-vertical-relative: text" o:spid="_x0000_s1026" type="#_x0000_t75"><imagedata src="file:///C:/DOCUME~1/myloon/LOCALS~1/Temp/msohtmlclip1/01/clip_image004.png" o:title="" cropbottom="29738f" cropright="53587f"></imagedata></shape>