最近项目中要用到Extjs,网上搜了写文档看了之后,写了个小Demo。
Demo描述:
将部门信息用树展示出来,点击树节点的某个部门之后,弹出一个窗口,该窗口中展示这个部门中员工的列表。
?
首先,到http://www.sencha.com/products/js/download.php下载Extjs3.2的发布包,因为要用到json lib,所以还要到http://sourceforge.net/projects/json-lib/files/json-lib/下载json lib。
?
mysql数据库脚本:
?
- DROP?TABLE?IF?EXISTS?`dept`;??
- CREATE?TABLE?`dept`?(??
- ??`deptno`?int(11)?NOT?NULL?AUTO_INCREMENT,??
- ??`deptname`?varchar(255)?NOT?NULL?DEFAULT?'',??
- ??`parentno`?int(11)?NOT?NULL?DEFAULT?'0',??
- ??PRIMARY?KEY?(`deptno`)??
- )?ENGINE=InnoDB?AUTO_INCREMENT=11?DEFAULT?CHARSET=utf8;??
- LOCK?TABLES?`dept`?WRITE;??
- /*!40000?ALTER?TABLE?`dept`?DISABLE?KEYS?*/;??
- INSERT?INTO?`dept`?VALUES?(1,'管理部',0);??
- INSERT?INTO?`dept`?VALUES?(2,'销售部',0);??
- INSERT?INTO?`dept`?VALUES?(3,'人力资源部',0);??
- INSERT?INTO?`dept`?VALUES?(4,'开发部',0);??
- INSERT?INTO?`dept`?VALUES?(5,'后勤部',0);??
- INSERT?INTO?`dept`?VALUES?(6,'软件开发部',4);??
- INSERT?INTO?`dept`?VALUES?(7,'增值开发部',4);??
- INSERT?INTO?`dept`?VALUES?(8,'增值销售部',2);??
- INSERT?INTO?`dept`?VALUES?(9,'产品销售部',2);??
- INSERT?INTO?`dept`?VALUES?(10,'人妖部',3);??
- /*!40000?ALTER?TABLE?`dept`?ENABLE?KEYS?*/;??
- UNLOCK?TABLES;??
- DROP?TABLE?IF?EXISTS?`emp`;??
- CREATE?TABLE?`emp`?(??
- ??`empno`?int(11)?NOT?NULL?AUTO_INCREMENT,??
- ??`empname`?varchar(255)?NOT?NULL?DEFAULT?'',??
- ??`gender`?int(11)?NOT?NULL?DEFAULT?'0',??
- ??`job`?varchar(255)?NOT?NULL?DEFAULT?'',??
- ??`deptno`?int(11)?NOT?NULL?DEFAULT?'0',??
- ??PRIMARY?KEY?(`empno`),??
- ??KEY?`fk_deptno`?(`deptno`)??
- )?ENGINE=InnoDB?AUTO_INCREMENT=11?DEFAULT?CHARSET=utf8;??
- LOCK?TABLES?`emp`?WRITE;??
- INSERT?INTO?`emp`?VALUES?(1,'陈一',1,'staff?boss',1);??
- INSERT?INTO?`emp`?VALUES?(2,'黄二',1,'technical?boss',1);??
- INSERT?INTO?`emp`?VALUES?(3,'张三',0,'human?resouce',3);??
- INSERT?INTO?`emp`?VALUES?(4,'李四',1,'developer?leader',6);??
- INSERT?INTO?`emp`?VALUES?(5,'王五',1,'clerk',10);??
- INSERT?INTO?`emp`?VALUES?(6,'赵六',1,'clerk',6);??
- INSERT?INTO?`emp`?VALUES?(7,'钱七',1,'executor',6);??
- INSERT?INTO?`emp`?VALUES?(8,'孙八',1,'super?man',6);??
- INSERT?INTO?`emp`?VALUES?(9,'方九',0,'oh,?god',6);??
- INSERT?INTO?`emp`?VALUES?(10,'无名氏',0,'无语',6);??
- UNLOCK?TABLES;??
- ALTER?TABLE?`emp`??
- ADD?CONSTRAINT?`fk_deptno`?FOREIGN?KEY?(`deptno`)?REFERENCES?`dept`?(`deptno`);??
?
?
?
下面建立web工程:
分别新建DeptModel,EmpModel,TreeModel和PageModel
DeptModel.java:
?
- public?class?DeptModel?{??
- ????private?int?deptno;??
- ????private?String?deptname;??
- ????private?int?parentno;??
- ?????????...??
- }??
?
?
EmpModel.java:
?
- public?class?EmpModel?{??
- ????private?Integer?empno;??
- ????private?String?empname;??
- ????private?String?gender;??
- ????private?String?job;??
- ????private?Integer?deptno;??
- ?????????...??
- }??
?
?
TreeModel.java,用于生成部门树的模型:
?
- public?class?TreeModel?{??
- ????private?int?id;??
- ????private?String?text;??
- ????private?boolean?leaf;??
- ????private?List<TreeModel>?children?=?new?ArrayList<TreeModel>(0);??
- ????public?TreeModel(){??
- ??????????
- ????}??
- ????/**?
- ?????*?根据部门列表获取形如?[{id:"",text:"",leaf:,children:[]},{...},...]的JSON字符串?
- ?????*?@param?models?部门列表List<DeptModel>?
- ?????*?@return?JSON格式的字符串,用于生成ext树?
- ?????*/??
- ????public?String?getJsonTreeModelString(List<DeptModel>?models){??
- ????????List<TreeModel>?lst?=?new?ArrayList<TreeModel>(0);??
- ????????for(DeptModel?dm?:?models){??
- ????????????if(dm.getParentno()==0){??
- ????????????????TreeModel?root?=?new?TreeModel();??
- ????????????????root.setId(dm.getDeptno());??
- ????????????????root.setText(dm.getDeptname());??
- ????????????????List<TreeModel>?children?=?getChildren(models,root);??//递归获取子集 ??
- ????????????????if(children.size()>0){??
- ????????????????????root.setLeaf(false);??
- ????????????????????root.setChildren(children);??
- ????????????????}else{??
- ????????????????????root.setLeaf(true);??
- ????????????????????root.setChildren(new?ArrayList<TreeModel>(0));??
- ????????????????}??
- ????????????????lst.add(root);??
- ????????????}??
- ????????}??
- ????????JsonConfig?config?=?new?JsonConfig();??
- ????????config.setExcludes(new?String[]{"models"});??
- ????????config.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);?????
- ????????return?JSONArray.fromObject(lst,config).toString();??
- ????}??
- ????/**?
- ?????*?递归获取节点的子集的方法?
- ?????*?@param?models?部门列表?
- ?????*?@param?parentModel?根节点,即deptno=0的根节点部门?
- ?????*?@return?List<TreeModel>?树模型列表?
- ?????*/??
- ????public?List<TreeModel>?getChildren(List<DeptModel>?models,TreeModel?parentModel){??
- ????????List<TreeModel>?lst?=?new?ArrayList<TreeModel>(0);??
- ????????for(DeptModel?dm?:?models){??
- ????????????if(parentModel.getId()?==?dm.getParentno()){??
- ????????????????TreeModel?tm?=?new?TreeModel();??
- ????????????????tm.setId(dm.getDeptno());??
- ????????????????tm.setText(dm.getDeptname());??
- ????????????????List<TreeModel>?children?=?getChildren(models,tm);??
- ????????????????if(children.size()>0){??
- ????????????????????tm.setLeaf(false);??
- ????????????????????tm.setChildren(children);??
- ????????????????}else{??
- ????????????????????tm.setLeaf(true);??
- ????????????????????tm.setChildren(new?ArrayList<TreeModel>(0));??
- ????????????????}??
- ????????????????lst.add(tm);??
- ????????????}??
- ????????}??
- ????????return?lst;??
- ????}??
- ?????????//省略getter,setter方法... ??
- }??
?
?
PageModel.java,用于分页的模型:
?
- public?class?PageModel?{??
- ????private?int?total;??
- ????private?List?lst;??
- ?????????...??
- }??
?
?
?
下面添加工程对Extjs3.2的支持:
解压ext-3.2.0.zip到某个路径,复制adapter、pkgs、resource文件夹、ext-3.2.0/src/locale/ext-lang-zh_CN.js和ext-3.2.0/ext-all.js到WebRoot/js下面,这样就完成了对Extjs功能的支持。
?
接下来完成从数据库获取部门信息和人员信息并转换成JSON格式:
deptProcessor.jsp:
?
- <%@?page?language="java"?pageEncoding="UTF-8"%>??
- <%@?page?import="com.model.TreeModel"?%>??
- <%@?page?import="com.model.DeptModel"?%>??
- <%@?page?import="java.sql.*,java.util.*"?%>??
- ????<%??
- ????????Class.forName("com.mysql.jdbc.Driver");??
- ????????java.sql.Connection?conn?=?java.sql.DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","root");??
- ????????PreparedStatement?pstmt?=?conn.prepareStatement("select?*?from?dept");??
- ????????ResultSet?rs?=?pstmt.executeQuery();??
- ????????List<DeptModel>?models?=?new?ArrayList<DeptModel>();??
- ????????while(rs.next()){??
- ????????????DeptModel?model?=?new?DeptModel();??
- ????????????model.setDeptno(rs.getInt("deptno"));??
- ????????????model.setDeptname(rs.getString("deptname"));??
- ????????????model.setParentno(rs.getInt("parentno"));??
- ????????????models.add(model);??
- ????????}??
- ????????String?jsonTreeModelString?=?new?TreeModel().getJsonTreeModelString(models);??
- ????????out.println(jsonTreeModelString);??
- ????%>??
?
?
?
empProcessor.jsp:
?
- <%@?page?language="java"?pageEncoding="UTF-8"%>??
- <%@?page?import="com.model.EmpModel"?%>??
- <%@?page?import="com.model.PageModel"?%>??
- <%@?page?import="net.sf.json.JSONObject"?%>??
- <%@?page?import="java.sql.*,java.util.*"?%>??
- ????<%??
- ????????Integer?deptno?=?-1;??
- ????????Integer?start?=?0;??
- ????????Integer?limit?=?0;??
- ????????if(request.getParameter("deptno")?!=?null){??
- ????????????deptno?=?Integer.parseInt(request.getParameter("deptno").toString());??
- ????????}??
- ????????if(request.getParameter("start")?!=?null){??
- ????????????start?=?Integer.parseInt(request.getParameter("start").toString());??
- ????????}??
- ????????if(request.getParameter("limit")?!=?null){??
- ????????????limit?=?Integer.parseInt(request.getParameter("limit").toString());??
- ????????}??
- ????????Class.forName("com.mysql.jdbc.Driver");??
- ????????java.sql.Connection?conn?=?java.sql.DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","root");??
- ????????PreparedStatement?pstmt?=?conn.prepareStatement("select?*?from?emp?where?deptno=??limit???,?");??
- ????????pstmt.setInt(1,deptno);??
- ????????pstmt.setInt(2,start);??
- ????????pstmt.setInt(3,limit);??
- ????????ResultSet?rs?=?pstmt.executeQuery();??
- ????????List<EmpModel>?models?=?new?ArrayList<EmpModel>();??
- ????????while(rs.next()){??
- ????????????EmpModel?model?=?new?EmpModel();??
- ????????????model.setEmpno(rs.getInt("empno"));??
- ????????????model.setEmpname(rs.getString("empname"));??
- ????????????model.setGender(rs.getInt("gender")==1?"男":"女");??
- ????????????model.setJob(rs.getString("job"));??
- ????????????model.setDeptno(rs.getInt("deptno"));??
- ????????????models.add(model);??
- ????????}??
- ????????pstmt?=?conn.prepareStatement("select?count(*)?from?emp?where?deptno=?");??
- ????????pstmt.setInt(1,deptno);??
- ????????rs?=?pstmt.executeQuery();??
- ????????int?total?=?0;??
- ????????if(rs.next()){??
- ????????????total?=?rs.getInt(1);??
- ????????}??
- ????????PageModel?pageModel?=?new?PageModel();??
- ????????pageModel.setTotal(total);??
- ????????pageModel.setLst(models);??
- ????????String?jsonEmpModelString?=?JSONObject.fromObject(pageModel).toString();??
- ????????out.println(jsonEmpModelString);??
- ????%>??
?
?
?
最后列用Extjs提供的TreePanel和Window,GridPanel分别显示部门和人员信息:
tree.jsp:
?
- <%@?page?language="java"?pageEncoding="UTF-8"%>??
- <!DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?4.01?Transitional//EN">??
- <html>??
- ??<head>??
- ????<title>Extjs?Tree?Demo</title>??
- ????<meta?http-equiv="pragma"?content="no-cache">??
- ????<meta?http-equiv="cache-control"?content="no-cache">??
- ????<meta?http-equiv="expires"?content="0">??????
- ????<meta?http-equiv="keywords"?content="keyword1,keyword2,keyword3">??
- ????<meta?http-equiv="description"?content="This?is?my?page">??
- ????<link?rel="stylesheet"?type="text/css"?href="js/extjs/resources/css/ext-all.css"?mce_href="js/extjs/resources/css/ext-all.css"?/>??
- ????<mce:script?src="js/extjs/adapter/ext/ext-base.js"?mce_src="js/extjs/adapter/ext/ext-base.js"></mce:script>??
- ????<mce:script?src="js/extjs/ext-all.js"?mce_src="js/extjs/ext-all.js"></mce:script>??
- ????<mce:script?src="js/extjs/ext-lang-zh_CN.js"?mce_src="js/extjs/ext-lang-zh_CN.js"></mce:script>??
- ????<mce:script?type="text/javascript"><!--??
- ????????Ext.onReady(function(){??
- ????????????//生成部门树结构 ??
- ????????????var?treeLoader?=?new?Ext.tree.TreeLoader({??
- ????????????????dataUrl:"deptProcessor.jsp"??
- ????????????});???????
- ????????????var?rootNode?=?new?Ext.tree.AsyncTreeNode({??
- ????????????????text:?'所有部门'??
- ????????????});??
- ????????????var?tree?=?new?Ext.tree.TreePanel({??
- ????????????????renderTo:'treecontainer',??
- ????????????????loader:?treeLoader,??
- ????????????????root:?rootNode,??
- ????????????????width:200,??
- ????????????????height:300,??
- ????????????????listeners:{??
- ????????????????????click:showEmps??
- ????????????????}??
- ????????????});??
- ????????????tree.expandAll();??
- ????????});??
- ????????//点击部门节点后的事件处理 ??
- ????????function?showEmps(n){??
- ????????????var?deptno?=?n.attributes.id;??
- ????????????var?deptname?=?n.attributes.text;??
- ????????????var?win?=?new?Ext.Window({??
- ????????????????title:deptname,??
- ????????????????width:500,??
- ????????????????height:300??
- ????????????});??
- ??????????????
- ????????????var?dataProxy?=?new?Ext.data.HttpProxy({??
- ????????????????url:"empProcessor.jsp?deptno="+deptno??
- ????????????});??
- ??????????????
- ????????????var?reader?=?new?Ext.data.JsonReader({totalProperty:"total",root:"lst"},[??
- ????????????????????"empno","empname","gender","job","deptno"??
- ????????????]);??
- ??????????????
- ????????????var?store?=?new?Ext.data.Store({??
- ????????????????proxy:dataProxy,??
- ????????????????reader:reader??
- ????????????});??
- ??????????????
- ????????????store.load({params:{start:0,limit:5}});??
- ??????????????
- ????????????var?columnModel?=?new?Ext.grid.ColumnModel([??
- ????????????????{header:"编号",width:100,dataIndex:"empno"},??
- ????????????????{header:"姓名",width:120,dataIndex:"empname"},??
- ????????????????{header:"性别",width:100,dataIndex:"gender"},??
- ????????????????{header:"职位",width:100,dataIndex:"job"}??
- ????????????]);??
- ????????????//分页 ??
- ????????????var?pageBar?=?new?Ext.PagingToolbar({??
- ????????????????store:store,??
- ????????????????pageSize:5,??
- ????????????????displayInfo:true,??
- ????????????????displayMsg:"当前为{0}-{1}条,共{2}条",??
- ????????????????emptyMsg:"没有记录"??
- ????????????});??
- ??????????????
- ????????????var?gridPanel?=?new?Ext.grid.GridPanel({??
- ????????????????width:480,??
- ????????????????autoHeight:true,??
- ????????????????cm:columnModel,??
- ????????????????store:store,??
- ????????????????bbar:pageBar??
- ????????????});??
- ????????????win.add(gridPanel);??
- ??????????????
- ????????????win.show(Ext.getBody());??
- ????????}??
- ??????
- //?--></mce:script> ??
- </head>??
- <body?style="padding:30px?20px"?mce_style="padding:30px?20px">??
- <div?id="treecontainer"?style="height:300px;?width:200px;"></div>??
- </body>??
- </html>?????
?
?
?
在浏览器中输入 http://127.0.0.1:8080/Extjs/tree.jsp?测试,效果如下:
<!--StartFragment -->