最近项目中要用到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 -->