关键字: extjs
收藏 Hibernate+Spring+Struts2+ExtJS开发CRUD功能 1、 入门: 各种开源框架环境及下载: Hibernate:3.x http://www.hibernate.org/ 需要hibernate core 和annotations 包。 Spring:2.x http://springframework.org/ Struts2:2.x http://struts.apache.org/2.x/ ExtJS:2.X http://extjs.com/ JSON:JSON可以到http://www.json.org/ 查看详细内容,这里使用json-lib http://json-lib.sourceforge.net/ 本所需要的包: 2、 配置: (1)首先是配置web.xml,配置方法可以在下面的配置文件代码注释中查看,这里主要是Struts2的配置: <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> 和Spring的配置: <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/*.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> Web.xml的全部文件: <?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>struts2</display-name> <!-- Spring ApplicationContext配置文件的路径,可使用通配符*,多个路径用,号分隔,此参数用于后面的Spring-Context loader --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/*.xml</param-value> </context-param> <!-- 著名 Character Encoding filter --> <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <!-- struts2 滤镜配置 --> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!--Spring ApplicationContext 载入 ,必须--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- Spring 刷新Introspector防止内存泄露 --> <listener> <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class> </listener> <!-- session超时定义,单位为分钟 --> <session-config> <session-timeout>10</session-timeout> </session-config> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> </web-app> (2)Hibernate配置: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!—-数据库驱动类名称 --> <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property> <!—-数据库用户名 --> <property name="hibernate.connection.username">MY</property> <property name="hibernate.default_schema">MY</property> <!—-数据库用户密码 --> <property name="hibernate.connection.password">MY</property> <!—-数据库连接字符串--> <property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:loon</property> <property name="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</property> <!—-控制台是否输出SQL语句 --> <property name="hibernate.show_sql">true</property> <mapping class="privilege.database.Level" /> </session-factory> </hibernate-configuration> (3)Spring基本配置:配置文件应该在WEB-INF/spring/下面 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans default-autowire="autodetect"> <!—如果用的是XML配置文件,sessionFactory用这个配置 "org.springframework.orm.hibernate3.LocalSessionFactoryBean" --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="configLocation"> <value>classpath:hibernate.cfg.xml</value> </property> <!-- 配置多个hibernate.cfg.xml <property name="configLocations"> <list> <value>classpath:hibernate_admin1.cfg.xml</value> <value>classpath:hibernate_admin2.cfg.xml</value> </list> </property> --> </bean> <!-- Hibernate 事务管理 --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true"> <property name="transactionManager" ref="transactionManager" /> <property name="transactionAttributes"> <props> <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop> <prop key="persist*">PROPAGATION_REQUIRED,-Exception</prop> <prop key="remove*">PROPAGATION_REQUIRED,-Exception</prop> <!-- <prop key="insert*">PROPAGATION_REQUIRED</prop> <prop key="save">PROPAGATION_REQUIRED</prop> <prop key="update*">PROPAGATION_REQUIRED</prop> <prop key="edit*">PROPAGATION_REQUIRED</prop> <prop key="del*">PROPAGATION_REQUIRED</prop> <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop> <prop key="query*">PROPAGATION_REQUIRED,readOnly</prop> <prop key="disPlay*">PROPAGATION_REQUIRES_NEW</prop> --> </props> </property> </bean> <bean id="LevelService" parent="baseTransactionProxy"> <property name="target"> <bean class="privilege.service.LevelService"> <property name="dao"> <bean class="privilege.dao.LevelDAO"> <property name="sessionFactory" ref="sessionFactory" /> </bean> </property> </bean> </property> </bean> <bean id="LevelAction" class="privilege.action.LevelAction"> <property name="levelService" ref="LevelService" /> </bean> </beans> (4)struts.xml文件的配置: <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package name="privilege" extends="struts-default"> <action name="LoadLevel" class="LevelAction" method="findLevelById"> <result>/resource/json_struts2.jsp</result> </action> <action name="LevelAjaxJsonData" class="LevelAction" method="jsonExecute"> <result>/resource/json_struts2.jsp</result> </action> </package> </struts> 3、 建立的项目目录: Root: /resource/ext2.0/ 将下载的ext-2.0-beta1.zip文件解压到该目录 /WEB-INF/web.xml /WEB-INF/lib /WEB-INF/classes/struts.xml /WEB-INF/spring/applicationContext.xml 4、 代码清单: Level.java import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name = "LOON_LEVEL") public class Level implements java.io.Serializable { private Long levelid; private String levelname; private String description; public Level() { } public Level(Long levelid) { this.levelid = levelid; } public Level(Long levelid, String levelname, String description) { this.levelid = levelid; this.levelname = levelname; this.description = description; } @Id @Column(name = "LEVELID", unique = true, nullable = false, precision = 5, scale = 0) public Long getLevelid() { return this.levelid; } public void setLevelid(Long levelid) { this.levelid = levelid; } @Column(name = "LEVELNAME", length = 64) public String getLevelname() { return this.levelname; } public void setLevelname(String levelname) { this.levelname = levelname; } @Column(name = "DESCRIPTION", length = 256) public String getDescription() { return this.description; } public void setDescription(String description) { this.description = description; } } ILevelDAO.java import java.util.List; public interface ILevelDAO { public Level findLevelById(Long id); public List<Level> findAllLevels(); public void persistLevel(Level level); public void removeLevel(Level level); public void removeById(Long id); } LevelDAO.java import java.util.List; import org.hibernate.Session; import org.springframework.orm.hibernate3.HibernateCallback; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; public class LevelDAO extends HibernateDaoSupport implements ILevelDAO { public LevelDAO() { super(); } public Level findLevelById(Long id) { return (Level) getHibernateTemplate().get(Level.class, id); } public List<Level> findAllLevels() { return getHibernateTemplate().loadAll(Level.class);// .find("from Level o");// } public void persistLevel(Level level) { getHibernateTemplate().saveOrUpdate(level); } public void removeLevel(Level level) { getHibernateTemplate().delete(level); } public void removeById(final Long id) { this.getHibernateTemplate().execute(new HibernateCallback() { public Object doInHibernate(Session session) { session.createQuery("delete from Level o where o.levelid=" + id + "").executeUpdate(); return 1; } }); } } ILevelService.java import java.util.List; public interface ILevelService { public Level findLevelById(Long id) throws Exception; public List<Level> findAllLevels() throws Exception; public List<Level> findLevelsByExample(Level level) throws Exception; public void persistLevel(Level level) throws Exception; public void removeLevel(Level level) throws Exception; public void removeLevelById(Long id) throws Exception; } LevelService.java import java.util.List; import privilege.dao.*; import privilege.database.Level; import org.springframework.context.ApplicationContext; public class LevelService implements ILevelService { private ILevelDAO dao; private static final String SERVICE_BEAN_ID = "LevelService"; public LevelService() { super(); } public static ILevelService getInstance(ApplicationContext context) { return (ILevelService) context.getBean(SERVICE_BEAN_ID); } public Level findLevelById(Long id) throws Exception { try { return getDao().findLevelById(id); } catch (RuntimeException e) { throw new Exception("findLevelById failed with the id " + id + ": " + e.getMessage()); } } public void persistLevel(Level level) throws Exception { try { getDao().persistLevel(level); } catch (RuntimeException e) { throw new Exception("persistLevel failed: " + e.getMessage()); } } public void removeLevel(Level level) throws Exception { try { getDao().removeLevel(level); } catch (RuntimeException e) { throw new Exception("removeLevel failed: " + e.getMessage()); } } public void removeLevelById(Long id) throws Exception { try { getDao().removeById(id); } catch (RuntimeException e) { throw new Exception("removeLevel failed: " + e.getMessage()); } } public void setDao(ILevelDAO dao) { this.dao = dao; } public ILevelDAO getDao() { return this.dao; } } ExtJSONActionSuport.java 辅助类,继承了ActionSupport import com.opensymphony.xwork2.ActionSupport; public class ExtJSONActionSuport extends ActionSupport { private int totalCount = 0;// 总数 private transient int start = 0;// 开始数 private transient int limit = 0;// 限制数量 private String jsonString = ""; public String getJsonString() { return jsonString; } public void setJsonString(String jsonString) { this.jsonString = jsonString; } public String jsonExecute() throws Exception { return super.execute(); } public int getTotalCount() { return totalCount; } public void setTotalCount(int totalCount) { this.totalCount = totalCount; } public int getStart() { return start; } public void setStart(int start) { this.start = start; } public int getLimit() { return limit; } public void setLimit(int limit) { this.limit = limit; } } LevelAction.java import java.util.List; import java.util.ArrayList; import javax.servlet.http.HttpSession; import org.apache.struts2.ServletActionContext; import net.sf.json.JSONArray; import privilege.database.Level; import privilege.service.*; import commons.utils.action.ExtJSONActionSuport; public class LevelAction extends ExtJSONActionSuport { private static final long serialVersionUID = 1L; private Level level = null; private List<Level> levels = new ArrayList<Level>(0); private ILevelService levelService = null; private String delData; public String execute() { return this.SUCCESS; } @Override public String jsonExecute() throws Exception { if (this.getDelData() != null && !"".equals(this.getDelData())) { if (this.getDelData().indexOf(",") < 0) { this.levelService.removeLevelById(Long.parseLong(this.getDelData())); System.out.println("del_id:" + getDelData()); } else { String id[] = this.getDelData().split(","); for (int i = 0; i < id.length; i++) { System.out.println("del:" + id[i]); this.levelService.removeLevelById(Long.parseLong(id[i])); } } } HttpSession session = ServletActionContext.getRequest().getSession(); Object o = null;// session.getAttribute("Level_Data1"); if (o == null) { try { this.levels = this.getLevelService().findAllLevels(); session.setAttribute("Level_Data1", this.levels); System.out.println("query database"); } catch (Exception e) { e.printStackTrace(); } } else { this.setLevels(((List<Level>) o)); } this.setTotalCount(this.levels.size()); JSONArray array = JSONArray.fromObject(this.levels); // System.out.println(this.getStart() + "---" + this.getLimit()); this.setJsonString("{success:true,totalCount : " + this.getTotalCount() + ", list:" + array.toString() + "}"); // System.out.println(this.getJsonString()); return super.jsonExecute(); } /** * Find an entity by its id (primary key). * * @param id * @return The found entity instance or null if the entity does not exist. */ public String findLevelById(Long id) { try { this.level = this.getLevelService().findLevelById(id); } catch (Exception e) { e.printStackTrace(); } JSONArray array = JSONArray.fromObject(this.levels); this.setJsonString(array.toString()); return SUCCESS; } public String findLevelById() { System.out.println(this.level.getLevelid()); try { this.level = this.getLevelService().findLevelById(this.level.getLevelid()); } catch (Exception e) { e.printStackTrace(); } JSONArray array = JSONArray.fromObject(this.level); this.setJsonString(array.toString()); this.setJsonString("{success:true,totalCount:1,list:" + array.toString() + "}"); System.out.println(array.toString()); return SUCCESS; } /** * @return Return all persistent instances of the <code>Level</code> entity. */ public String getAllLevels() { try { this.levels = this.getLevelService().findAllLevels(); } catch (Exception e) { e.printStackTrace(); } return SUCCESS; } /** * Make the given instance managed and persistent. * * @return */ public String persistLevel() { System.out.println(this.level.getLevelid() + "---" + this.level.getLevelname() + "---" + this.level.getDescription()); this.setJsonString("{success:true}"); try { this.getLevelService().persistLevel(this.getLevel()); } catch (Exception e) { e.printStackTrace(); } return SUCCESS; } /** * Remove the given persistent instance. * * @return */ public String removeLevel() { try { this.getLevelService().removeLevel(this.getLevel()); } catch (Exception e) { e.printStackTrace(); } return SUCCESS; } /** * Remove an entity by its id (primary key). * * * @return */ public String removeLevelById(Long id) { try { this.getLevelService().removeLevelById(id); } catch (Exception e) { e.printStackTrace(); } return SUCCESS; } public Level getLevel() { return level; } public void setLevel(Level level) { this.level = level; } public List<Level> getLevels() { return levels; } public void setLevels(List<Level> levels) { this.levels = levels; } public ILevelService getLevelService() { return levelService; } public void setLevelService(ILevelService levelService) { this.levelService = levelService; } public String getDelData() { return delData; } public void setDelData(String delData) { this.delData = delData; } } 配置spring,添加: <bean id="LevelService" parent="baseTransactionProxy"> <property name="target"> <bean class="privilege.service.LevelService"> <property name="dao"> <bean class="privilege.dao.LevelDAO"> <property name="sessionFactory" ref="sessionFactory" /> </bean> </property> </bean> </property> </bean> <bean id="LevelAction" class="privilege.action.LevelAction"> <property name="levelService" ref="LevelService" /> </bean> 配置struts.xml: 添加操作配置: <action name="AddLevel" class="LevelAction" method="persistLevel"> <result>/resource/json_struts2.jsp</result> </action> 修改时载入数据操作配置: <action name="LoadLevel" class="LevelAction" method="findLevelById"> <result>/resource/json_struts2.jsp</result> </action> 列表查询和删除数据时操作配置: <action name="LevelAjaxJsonData" class="LevelAction" method="jsonExecute"> <result>/resource/json_struts2.jsp</result> </action> json_struts2.jsp : 这个页面是一个公用的页面,服务器段向客户端传输时用于JSON字符串的输出,特别注意的是: <s:property>标签的escape属性一定要是false,默认是true,不然输出的JSON字符串被转码。 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><%@ taglib prefix="s" uri="/struts-tags"%> <s:property value="jsonString" escape="false" /> Level.jsp: <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>页面</title> 导入所需要的javascript类库和样式表: <link rel="stylesheet" type="text/css" href="/my/resource/ext2.0/resources/css/ext-all.css" /> <link rel="stylesheet" type="text/css" href="/my/resource/ext2.0/init.css" /> <script src="/my/resource/ext2.0/adapter/ext/ext-base.js" type="text/javascript"></script> <script src="/my/resource/ext2.0/ext-core.js" type="text/javascript"></script> <script src="/my/resource/ext2.0/ext-all.js" type="text/javascript"></script> Init.jsp是自定义的javascript文件,这里有一些需要动态处理的内容,所以以jsp后缀名的方式导入,这个文件的内容可以参考Extjs解压后目录中examples/examples.js文件: <script src="/my/resource/ext2.0/init.jsp" type="text/javascript"></script> <script src="/my/resource/ext2.0/source/locale/ext-lang-zh_CN.js" type="text/javascript"></script> Level.js是整个界面所写的js: <SCRIPT type="text/javascript" src="Level.js"></SCRIPT> <SCRIPT type="text/javascript"> Ext.BLANK_IMAGE_URL = /my/resource/ext2.0/resources/images/default/s.gif'; </SCRIPT> <STYLE type="text/css"> .ss { text-align: left;; } .icon-grid { background-image: url(grid.png) !important; } .add { background-image: url(new.png) !important; } .edit { background-image: url(edit.png) !important; } .remove { background-image: url(del.png) !important; } </STYLE> </head> <body class="x-vista"> <div id="topic-grid"></div> <div id="topic-win" class="x-hidden"> <div class="x-window-header">Hello Dialog</div> <div id="topic-tabs"></div> </div> </body> </html> Level.js文件: myinit();//初始化 Ext.onReady(function() { Ext.QuickTips.init(); var newFormWin; var form1; //定义一个JsonReader对象,用于表格列表数据显示,即grid对象 var _jsonReader = new Ext.data.JsonReader( { root : 'list', totalProperty : 'totalCount', id : 'levelid', successProperty : '@success' }, [ { name : 'levelid', mapping : 'levelid', type : 'int' }, { name : 'levelname', mapping : 'levelname' }, { name : 'description', mapping : 'description' }]); // Store对象,注意proxy配置参数,如果url : 'LevelAjaxJsonData.action'与程序在同一应用下面,就用new Ext.data.HttpProxy,如果不在同一应用中要用Ext.data.ScriptTagProxy对象 var ds = new Ext.data.Store( { proxy : new Ext.data.HttpProxy( { url : 'LevelAjaxJsonData.action' }), // reader : _jsonReader }); ds.setDefaultSort('levelid', 'desc');//设置默认的排序字段 // ColumnModel对象,用于grid对象中的列格式化配置 var cm = new Ext.grid.ColumnModel([new Ext.grid.RowNumberer(), { id : 'levelid', header : '序号', dataIndex : 'levelid', width : 40 }, { header : "级别名称", dataIndex : 'levelname', width : 50, sortable : true, locked : false }, { header : "描述", dataIndex : 'description', width : 100 }]); // by default columns are sortable cm.defaultSortable = true; // GridPanel对象 var grid = new Ext.grid.GridPanel( { // var grid = new Ext.grid.EditorGridPanel( { collapsible : true,// 是否可以展开 animCollapse : false,// 展开时是否有动画效果 title : '级别管理', iconCls : 'icon-grid', store : ds, cm : cm, renderTo : 'topic-grid', viewConfig : { forceFit : true }, /* * // 添加内陷的按钮 buttons : [ { text : '保存' }, { text : '取消' }], * buttonAlign : 'center',// 按钮对齐 * */ // 添加分页工具栏 bbar : new Ext.PagingToolbar( { pageSize : 30, store : ds, displayInfo : true, displayMsg : '显示 {0}-{1}条 / 共 {2} 条', emptyMsg : "无数据。", items : ['-', { pressed : true, enableToggle : true, text : '按钮', cls : 'x-btn-text-icon details', toggleHandler : ptb_bt1 }] }), // 添加内陷的工具条 tbar : [ { id : 'New1', text : ' 新建 ', tooltip : '新建一个表单', iconCls : 'add', handler : function() { ptb_bt1(); } }, '-', { text : '修改', tooltip : '修改', iconCls : 'edit', handler : function() { ptb_bt2(); } }, '-', { text : '删除', tooltip : '删除被选择的内容', iconCls : 'remove', handler : function() { ptb_bt3(); } }], width : 700, height : 400, frame : true, loadMask : true,// 载入遮罩动画 autoShow : true }); //数据载入 ds.load( { params : { start : 0,//开始数 limit : 30,//每次载入数量,服务器段就根据这两个参数来处理数据分页 forumId : 4 } }); grid.render(); //添加行双击事件,双击是可以打开修改窗口 grid.on("rowdblclick", function(grid) { loadFormData(grid); }); // 载入被选择的数据行的表单数据 var loadFormData = function(grid) { var _record = grid.getSelectionModel().getSelected(); if (!_record) {//这里判断是否有行已经被选择 Ext.example.msg('修改操作', '请选择要修改的一项!'); } else { myFormWin(); form1.form.load( { url : 'LoadLevel.action?level.levelid=' + _record.get('levelid'), waitMsg : '正在载入数据...', failure : function() { Ext.example.msg('编辑', '载入失败'); }, success : function() { Ext.example.msg('编辑', '载入成功!'); } }); } } // 分页工具栏按钮--新建事件 var ptb_bt1 = function() { myFormWin(); }; // 修改操作事件 var ptb_bt2 = function() { loadFormData(grid); }; // 删除事件 var ptb_bt3 = function() { var _record = grid.getSelectionModel().getSelected(); if (_record) {//判断是否有行被选择 Ext.MessageBox.confirm('确认删除', '你确认要删除这条数据吗?', function(btn) { if (btn == "yes") { var m = grid.getSelections();//所有被选择的行 var jsonData = "";// for (var i = 0, len = m.length;i < len; i++) { var ss = m[i].get("levelid"); if (i == 0) { jsonData = jsonData + ss; } else { jsonData = jsonData + "," + ss; } ds.remove(m[i]); } ds.load( { params : { start : 0, limit : 30, delData : jsonData//这里是向服务器段发送的数据信息,一般采用JSON协议,这儿直接采用,只发送用逗号分割的ID号序列, 以方便 } }); // Ext.example.msg('---删除操作---', '你删除的数据是'); } }); } else { Ext.example.msg('删除操作', '请选择要删除的数据项!'); } }; // form_win定义一个Window对象,用于新建和修改时的弹出窗口。 var myFormWin = function() { // create the window on the first click and reuse on subsequent // clicks if (!newFormWin) { newFormWin = new Ext.Window( { el : 'topic-win', layout : 'fit', width : 400, height : 300, closeAction : 'hide', plain : true, title : '窗口', items : form1, reader : _jsonReader }); } newFormWin.show('New1'); } //用窗体Form的JsonReader对象,修改时数据载入解析 var _jsonFormReader = new Ext.data.JsonReader( { root : 'list', totalProperty : 'totalCount', id : 'levelid', successProperty : '@success' }, [ { name : 'level.levelid', mapping : 'levelid', type : 'int' }, { name : 'level.levelname', mapping : 'levelname' }, { name : 'level.description', mapping : 'description' }]); // 窗体 form1 = new Ext.FormPanel( { // collapsible : true,// 是否可以展开 labelWidth : 75, // label settings here cascade unless overridden url : 'AddLevel.action', frame : true, title : '添加级别', bodyStyle : 'padding:5px 5px 0', width : 350, waitMsgTarget : true, reader : _jsonFormReader, defaults : { width : 230 }, defaultType : 'textfield', items : [ { fieldLabel : '级别ID', name : 'level.levelid', allowBlank : false }, { fieldLabel : '级别名称', name : 'level.levelname', allowBlank : false }, new Ext.form.TextArea( { fieldLabel : '描述', name : 'level.description', growMin : 234 })], buttons : [ { text : '保存', disabled : false, handler : function() { if (form1.form.isValid()) { form1.form.submit( { url : 'AddLevel.action', success : function(from, action) { Ext.example.msg('保存成功', '添加级别成功!'); ds.load( { params : { start : 0, limit : 30, forumId : 4 } }); }, failure : function(form, action) { Ext.example.msg('保存失败', '添加级别失败!'); }, waitMsg : '正在保存数据,稍后...' }); dialog.hide(); } else { Ext.Msg.alert('信息', '请填写完成再提交!'); } } }, { text : '取消', handler : function() { newFormWin.hide(); } }] }); }); 5、 运行时的一些图(Firefox 2.0): 数据列表: 新建: 修改: 未选择数据行 选择数据行后,单击修改按钮(双击数据行可直接修改) 删除数据: 删除时确认 确认后删除数据: 源代码下载: 源代码下载:
收藏 Hibernate+Spring+Struts2+ExtJS开发CRUD功能 1、 入门: 各种开源框架环境及下载: Hibernate:3.x http://www.hibernate.org/ 需要hibernate core 和annotations 包。 Spring:2.x http://springframework.org/ Struts2:2.x http://struts.apache.org/2.x/ ExtJS:2.X http://extjs.com/ JSON:JSON可以到http://www.json.org/ 查看详细内容,这里使用json-lib http://json-lib.sourceforge.net/ 本所需要的包: 2、 配置: (1)首先是配置web.xml,配置方法可以在下面的配置文件代码注释中查看,这里主要是Struts2的配置: <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> 和Spring的配置: <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/*.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> Web.xml的全部文件: <?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>struts2</display-name> <!-- Spring ApplicationContext配置文件的路径,可使用通配符*,多个路径用,号分隔,此参数用于后面的Spring-Context loader --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/*.xml</param-value> </context-param> <!-- 著名 Character Encoding filter --> <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <!-- struts2 滤镜配置 --> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!--Spring ApplicationContext 载入 ,必须--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- Spring 刷新Introspector防止内存泄露 --> <listener> <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class> </listener> <!-- session超时定义,单位为分钟 --> <session-config> <session-timeout>10</session-timeout> </session-config> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> </web-app> (2)Hibernate配置: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!—-数据库驱动类名称 --> <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property> <!—-数据库用户名 --> <property name="hibernate.connection.username">MY</property> <property name="hibernate.default_schema">MY</property> <!—-数据库用户密码 --> <property name="hibernate.connection.password">MY</property> <!—-数据库连接字符串--> <property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:loon</property> <property name="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</property> <!—-控制台是否输出SQL语句 --> <property name="hibernate.show_sql">true</property> <mapping class="privilege.database.Level" /> </session-factory> </hibernate-configuration> (3)Spring基本配置:配置文件应该在WEB-INF/spring/下面 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans default-autowire="autodetect"> <!—如果用的是XML配置文件,sessionFactory用这个配置 "org.springframework.orm.hibernate3.LocalSessionFactoryBean" --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="configLocation"> <value>classpath:hibernate.cfg.xml</value> </property> <!-- 配置多个hibernate.cfg.xml <property name="configLocations"> <list> <value>classpath:hibernate_admin1.cfg.xml</value> <value>classpath:hibernate_admin2.cfg.xml</value> </list> </property> --> </bean> <!-- Hibernate 事务管理 --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean> <bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true"> <property name="transactionManager" ref="transactionManager" /> <property name="transactionAttributes"> <props> <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop> <prop key="persist*">PROPAGATION_REQUIRED,-Exception</prop> <prop key="remove*">PROPAGATION_REQUIRED,-Exception</prop> <!-- <prop key="insert*">PROPAGATION_REQUIRED</prop> <prop key="save">PROPAGATION_REQUIRED</prop> <prop key="update*">PROPAGATION_REQUIRED</prop> <prop key="edit*">PROPAGATION_REQUIRED</prop> <prop key="del*">PROPAGATION_REQUIRED</prop> <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop> <prop key="query*">PROPAGATION_REQUIRED,readOnly</prop> <prop key="disPlay*">PROPAGATION_REQUIRES_NEW</prop> --> </props> </property> </bean> <bean id="LevelService" parent="baseTransactionProxy"> <property name="target"> <bean class="privilege.service.LevelService"> <property name="dao"> <bean class="privilege.dao.LevelDAO"> <property name="sessionFactory" ref="sessionFactory" /> </bean> </property> </bean> </property> </bean> <bean id="LevelAction" class="privilege.action.LevelAction"> <property name="levelService" ref="LevelService" /> </bean> </beans> (4)struts.xml文件的配置: <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package name="privilege" extends="struts-default"> <action name="LoadLevel" class="LevelAction" method="findLevelById"> <result>/resource/json_struts2.jsp</result> </action> <action name="LevelAjaxJsonData" class="LevelAction" method="jsonExecute"> <result>/resource/json_struts2.jsp</result> </action> </package> </struts> 3、 建立的项目目录: Root: /resource/ext2.0/ 将下载的ext-2.0-beta1.zip文件解压到该目录 /WEB-INF/web.xml /WEB-INF/lib /WEB-INF/classes/struts.xml /WEB-INF/spring/applicationContext.xml 4、 代码清单: Level.java import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name = "LOON_LEVEL") public class Level implements java.io.Serializable { private Long levelid; private String levelname; private String description; public Level() { } public Level(Long levelid) { this.levelid = levelid; } public Level(Long levelid, String levelname, String description) { this.levelid = levelid; this.levelname = levelname; this.description = description; } @Id @Column(name = "LEVELID", unique = true, nullable = false, precision = 5, scale = 0) public Long getLevelid() { return this.levelid; } public void setLevelid(Long levelid) { this.levelid = levelid; } @Column(name = "LEVELNAME", length = 64) public String getLevelname() { return this.levelname; } public void setLevelname(String levelname) { this.levelname = levelname; } @Column(name = "DESCRIPTION", length = 256) public String getDescription() { return this.description; } public void setDescription(String description) { this.description = description; } } ILevelDAO.java import java.util.List; public interface ILevelDAO { public Level findLevelById(Long id); public List<Level> findAllLevels(); public void persistLevel(Level level); public void removeLevel(Level level); public void removeById(Long id); } LevelDAO.java import java.util.List; import org.hibernate.Session; import org.springframework.orm.hibernate3.HibernateCallback; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; public class LevelDAO extends HibernateDaoSupport implements ILevelDAO { public LevelDAO() { super(); } public Level findLevelById(Long id) { return (Level) getHibernateTemplate().get(Level.class, id); } public List<Level> findAllLevels() { return getHibernateTemplate().loadAll(Level.class);// .find("from Level o");// } public void persistLevel(Level level) { getHibernateTemplate().saveOrUpdate(level); } public void removeLevel(Level level) { getHibernateTemplate().delete(level); } public void removeById(final Long id) { this.getHibernateTemplate().execute(new HibernateCallback() { public Object doInHibernate(Session session) { session.createQuery("delete from Level o where o.levelid=" + id + "").executeUpdate(); return 1; } }); } } ILevelService.java import java.util.List; public interface ILevelService { public Level findLevelById(Long id) throws Exception; public List<Level> findAllLevels() throws Exception; public List<Level> findLevelsByExample(Level level) throws Exception; public void persistLevel(Level level) throws Exception; public void removeLevel(Level level) throws Exception; public void removeLevelById(Long id) throws Exception; } LevelService.java import java.util.List; import privilege.dao.*; import privilege.database.Level; import org.springframework.context.ApplicationContext; public class LevelService implements ILevelService { private ILevelDAO dao; private static final String SERVICE_BEAN_ID = "LevelService"; public LevelService() { super(); } public static ILevelService getInstance(ApplicationContext context) { return (ILevelService) context.getBean(SERVICE_BEAN_ID); } public Level findLevelById(Long id) throws Exception { try { return getDao().findLevelById(id); } catch (RuntimeException e) { throw new Exception("findLevelById failed with the id " + id + ": " + e.getMessage()); } } public void persistLevel(Level level) throws Exception { try { getDao().persistLevel(level); } catch (RuntimeException e) { throw new Exception("persistLevel failed: " + e.getMessage()); } } public void removeLevel(Level level) throws Exception { try { getDao().removeLevel(level); } catch (RuntimeException e) { throw new Exception("removeLevel failed: " + e.getMessage()); } } public void removeLevelById(Long id) throws Exception { try { getDao().removeById(id); } catch (RuntimeException e) { throw new Exception("removeLevel failed: " + e.getMessage()); } } public void setDao(ILevelDAO dao) { this.dao = dao; } public ILevelDAO getDao() { return this.dao; } } ExtJSONActionSuport.java 辅助类,继承了ActionSupport import com.opensymphony.xwork2.ActionSupport; public class ExtJSONActionSuport extends ActionSupport { private int totalCount = 0;// 总数 private transient int start = 0;// 开始数 private transient int limit = 0;// 限制数量 private String jsonString = ""; public String getJsonString() { return jsonString; } public void setJsonString(String jsonString) { this.jsonString = jsonString; } public String jsonExecute() throws Exception { return super.execute(); } public int getTotalCount() { return totalCount; } public void setTotalCount(int totalCount) { this.totalCount = totalCount; } public int getStart() { return start; } public void setStart(int start) { this.start = start; } public int getLimit() { return limit; } public void setLimit(int limit) { this.limit = limit; } } LevelAction.java import java.util.List; import java.util.ArrayList; import javax.servlet.http.HttpSession; import org.apache.struts2.ServletActionContext; import net.sf.json.JSONArray; import privilege.database.Level; import privilege.service.*; import commons.utils.action.ExtJSONActionSuport; public class LevelAction extends ExtJSONActionSuport { private static final long serialVersionUID = 1L; private Level level = null; private List<Level> levels = new ArrayList<Level>(0); private ILevelService levelService = null; private String delData; public String execute() { return this.SUCCESS; } @Override public String jsonExecute() throws Exception { if (this.getDelData() != null && !"".equals(this.getDelData())) { if (this.getDelData().indexOf(",") < 0) { this.levelService.removeLevelById(Long.parseLong(this.getDelData())); System.out.println("del_id:" + getDelData()); } else { String id[] = this.getDelData().split(","); for (int i = 0; i < id.length; i++) { System.out.println("del:" + id[i]); this.levelService.removeLevelById(Long.parseLong(id[i])); } } } HttpSession session = ServletActionContext.getRequest().getSession(); Object o = null;// session.getAttribute("Level_Data1"); if (o == null) { try { this.levels = this.getLevelService().findAllLevels(); session.setAttribute("Level_Data1", this.levels); System.out.println("query database"); } catch (Exception e) { e.printStackTrace(); } } else { this.setLevels(((List<Level>) o)); } this.setTotalCount(this.levels.size()); JSONArray array = JSONArray.fromObject(this.levels); // System.out.println(this.getStart() + "---" + this.getLimit()); this.setJsonString("{success:true,totalCount : " + this.getTotalCount() + ", list:" + array.toString() + "}"); // System.out.println(this.getJsonString()); return super.jsonExecute(); } /** * Find an entity by its id (primary key). * * @param id * @return The found entity instance or null if the entity does not exist. */ public String findLevelById(Long id) { try { this.level = this.getLevelService().findLevelById(id); } catch (Exception e) { e.printStackTrace(); } JSONArray array = JSONArray.fromObject(this.levels); this.setJsonString(array.toString()); return SUCCESS; } public String findLevelById() { System.out.println(this.level.getLevelid()); try { this.level = this.getLevelService().findLevelById(this.level.getLevelid()); } catch (Exception e) { e.printStackTrace(); } JSONArray array = JSONArray.fromObject(this.level); this.setJsonString(array.toString()); this.setJsonString("{success:true,totalCount:1,list:" + array.toString() + "}"); System.out.println(array.toString()); return SUCCESS; } /** * @return Return all persistent instances of the <code>Level</code> entity. */ public String getAllLevels() { try { this.levels = this.getLevelService().findAllLevels(); } catch (Exception e) { e.printStackTrace(); } return SUCCESS; } /** * Make the given instance managed and persistent. * * @return */ public String persistLevel() { System.out.println(this.level.getLevelid() + "---" + this.level.getLevelname() + "---" + this.level.getDescription()); this.setJsonString("{success:true}"); try { this.getLevelService().persistLevel(this.getLevel()); } catch (Exception e) { e.printStackTrace(); } return SUCCESS; } /** * Remove the given persistent instance. * * @return */ public String removeLevel() { try { this.getLevelService().removeLevel(this.getLevel()); } catch (Exception e) { e.printStackTrace(); } return SUCCESS; } /** * Remove an entity by its id (primary key). * * * @return */ public String removeLevelById(Long id) { try { this.getLevelService().removeLevelById(id); } catch (Exception e) { e.printStackTrace(); } return SUCCESS; } public Level getLevel() { return level; } public void setLevel(Level level) { this.level = level; } public List<Level> getLevels() { return levels; } public void setLevels(List<Level> levels) { this.levels = levels; } public ILevelService getLevelService() { return levelService; } public void setLevelService(ILevelService levelService) { this.levelService = levelService; } public String getDelData() { return delData; } public void setDelData(String delData) { this.delData = delData; } } 配置spring,添加: <bean id="LevelService" parent="baseTransactionProxy"> <property name="target"> <bean class="privilege.service.LevelService"> <property name="dao"> <bean class="privilege.dao.LevelDAO"> <property name="sessionFactory" ref="sessionFactory" /> </bean> </property> </bean> </property> </bean> <bean id="LevelAction" class="privilege.action.LevelAction"> <property name="levelService" ref="LevelService" /> </bean> 配置struts.xml: 添加操作配置: <action name="AddLevel" class="LevelAction" method="persistLevel"> <result>/resource/json_struts2.jsp</result> </action> 修改时载入数据操作配置: <action name="LoadLevel" class="LevelAction" method="findLevelById"> <result>/resource/json_struts2.jsp</result> </action> 列表查询和删除数据时操作配置: <action name="LevelAjaxJsonData" class="LevelAction" method="jsonExecute"> <result>/resource/json_struts2.jsp</result> </action> json_struts2.jsp : 这个页面是一个公用的页面,服务器段向客户端传输时用于JSON字符串的输出,特别注意的是: <s:property>标签的escape属性一定要是false,默认是true,不然输出的JSON字符串被转码。 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><%@ taglib prefix="s" uri="/struts-tags"%> <s:property value="jsonString" escape="false" /> Level.jsp: <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="s" uri="/struts-tags"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>页面</title> 导入所需要的javascript类库和样式表: <link rel="stylesheet" type="text/css" href="/my/resource/ext2.0/resources/css/ext-all.css" /> <link rel="stylesheet" type="text/css" href="/my/resource/ext2.0/init.css" /> <script src="/my/resource/ext2.0/adapter/ext/ext-base.js" type="text/javascript"></script> <script src="/my/resource/ext2.0/ext-core.js" type="text/javascript"></script> <script src="/my/resource/ext2.0/ext-all.js" type="text/javascript"></script> Init.jsp是自定义的javascript文件,这里有一些需要动态处理的内容,所以以jsp后缀名的方式导入,这个文件的内容可以参考Extjs解压后目录中examples/examples.js文件: <script src="/my/resource/ext2.0/init.jsp" type="text/javascript"></script> <script src="/my/resource/ext2.0/source/locale/ext-lang-zh_CN.js" type="text/javascript"></script> Level.js是整个界面所写的js: <SCRIPT type="text/javascript" src="Level.js"></SCRIPT> <SCRIPT type="text/javascript"> Ext.BLANK_IMAGE_URL = /my/resource/ext2.0/resources/images/default/s.gif'; </SCRIPT> <STYLE type="text/css"> .ss { text-align: left;; } .icon-grid { background-image: url(grid.png) !important; } .add { background-image: url(new.png) !important; } .edit { background-image: url(edit.png) !important; } .remove { background-image: url(del.png) !important; } </STYLE> </head> <body class="x-vista"> <div id="topic-grid"></div> <div id="topic-win" class="x-hidden"> <div class="x-window-header">Hello Dialog</div> <div id="topic-tabs"></div> </div> </body> </html> Level.js文件: myinit();//初始化 Ext.onReady(function() { Ext.QuickTips.init(); var newFormWin; var form1; //定义一个JsonReader对象,用于表格列表数据显示,即grid对象 var _jsonReader = new Ext.data.JsonReader( { root : 'list', totalProperty : 'totalCount', id : 'levelid', successProperty : '@success' }, [ { name : 'levelid', mapping : 'levelid', type : 'int' }, { name : 'levelname', mapping : 'levelname' }, { name : 'description', mapping : 'description' }]); // Store对象,注意proxy配置参数,如果url : 'LevelAjaxJsonData.action'与程序在同一应用下面,就用new Ext.data.HttpProxy,如果不在同一应用中要用Ext.data.ScriptTagProxy对象 var ds = new Ext.data.Store( { proxy : new Ext.data.HttpProxy( { url : 'LevelAjaxJsonData.action' }), // reader : _jsonReader }); ds.setDefaultSort('levelid', 'desc');//设置默认的排序字段 // ColumnModel对象,用于grid对象中的列格式化配置 var cm = new Ext.grid.ColumnModel([new Ext.grid.RowNumberer(), { id : 'levelid', header : '序号', dataIndex : 'levelid', width : 40 }, { header : "级别名称", dataIndex : 'levelname', width : 50, sortable : true, locked : false }, { header : "描述", dataIndex : 'description', width : 100 }]); // by default columns are sortable cm.defaultSortable = true; // GridPanel对象 var grid = new Ext.grid.GridPanel( { // var grid = new Ext.grid.EditorGridPanel( { collapsible : true,// 是否可以展开 animCollapse : false,// 展开时是否有动画效果 title : '级别管理', iconCls : 'icon-grid', store : ds, cm : cm, renderTo : 'topic-grid', viewConfig : { forceFit : true }, /* * // 添加内陷的按钮 buttons : [ { text : '保存' }, { text : '取消' }], * buttonAlign : 'center',// 按钮对齐 * */ // 添加分页工具栏 bbar : new Ext.PagingToolbar( { pageSize : 30, store : ds, displayInfo : true, displayMsg : '显示 {0}-{1}条 / 共 {2} 条', emptyMsg : "无数据。", items : ['-', { pressed : true, enableToggle : true, text : '按钮', cls : 'x-btn-text-icon details', toggleHandler : ptb_bt1 }] }), // 添加内陷的工具条 tbar : [ { id : 'New1', text : ' 新建 ', tooltip : '新建一个表单', iconCls : 'add', handler : function() { ptb_bt1(); } }, '-', { text : '修改', tooltip : '修改', iconCls : 'edit', handler : function() { ptb_bt2(); } }, '-', { text : '删除', tooltip : '删除被选择的内容', iconCls : 'remove', handler : function() { ptb_bt3(); } }], width : 700, height : 400, frame : true, loadMask : true,// 载入遮罩动画 autoShow : true }); //数据载入 ds.load( { params : { start : 0,//开始数 limit : 30,//每次载入数量,服务器段就根据这两个参数来处理数据分页 forumId : 4 } }); grid.render(); //添加行双击事件,双击是可以打开修改窗口 grid.on("rowdblclick", function(grid) { loadFormData(grid); }); // 载入被选择的数据行的表单数据 var loadFormData = function(grid) { var _record = grid.getSelectionModel().getSelected(); if (!_record) {//这里判断是否有行已经被选择 Ext.example.msg('修改操作', '请选择要修改的一项!'); } else { myFormWin(); form1.form.load( { url : 'LoadLevel.action?level.levelid=' + _record.get('levelid'), waitMsg : '正在载入数据...', failure : function() { Ext.example.msg('编辑', '载入失败'); }, success : function() { Ext.example.msg('编辑', '载入成功!'); } }); } } // 分页工具栏按钮--新建事件 var ptb_bt1 = function() { myFormWin(); }; // 修改操作事件 var ptb_bt2 = function() { loadFormData(grid); }; // 删除事件 var ptb_bt3 = function() { var _record = grid.getSelectionModel().getSelected(); if (_record) {//判断是否有行被选择 Ext.MessageBox.confirm('确认删除', '你确认要删除这条数据吗?', function(btn) { if (btn == "yes") { var m = grid.getSelections();//所有被选择的行 var jsonData = "";// for (var i = 0, len = m.length;i < len; i++) { var ss = m[i].get("levelid"); if (i == 0) { jsonData = jsonData + ss; } else { jsonData = jsonData + "," + ss; } ds.remove(m[i]); } ds.load( { params : { start : 0, limit : 30, delData : jsonData//这里是向服务器段发送的数据信息,一般采用JSON协议,这儿直接采用,只发送用逗号分割的ID号序列, 以方便 } }); // Ext.example.msg('---删除操作---', '你删除的数据是'); } }); } else { Ext.example.msg('删除操作', '请选择要删除的数据项!'); } }; // form_win定义一个Window对象,用于新建和修改时的弹出窗口。 var myFormWin = function() { // create the window on the first click and reuse on subsequent // clicks if (!newFormWin) { newFormWin = new Ext.Window( { el : 'topic-win', layout : 'fit', width : 400, height : 300, closeAction : 'hide', plain : true, title : '窗口', items : form1, reader : _jsonReader }); } newFormWin.show('New1'); } //用窗体Form的JsonReader对象,修改时数据载入解析 var _jsonFormReader = new Ext.data.JsonReader( { root : 'list', totalProperty : 'totalCount', id : 'levelid', successProperty : '@success' }, [ { name : 'level.levelid', mapping : 'levelid', type : 'int' }, { name : 'level.levelname', mapping : 'levelname' }, { name : 'level.description', mapping : 'description' }]); // 窗体 form1 = new Ext.FormPanel( { // collapsible : true,// 是否可以展开 labelWidth : 75, // label settings here cascade unless overridden url : 'AddLevel.action', frame : true, title : '添加级别', bodyStyle : 'padding:5px 5px 0', width : 350, waitMsgTarget : true, reader : _jsonFormReader, defaults : { width : 230 }, defaultType : 'textfield', items : [ { fieldLabel : '级别ID', name : 'level.levelid', allowBlank : false }, { fieldLabel : '级别名称', name : 'level.levelname', allowBlank : false }, new Ext.form.TextArea( { fieldLabel : '描述', name : 'level.description', growMin : 234 })], buttons : [ { text : '保存', disabled : false, handler : function() { if (form1.form.isValid()) { form1.form.submit( { url : 'AddLevel.action', success : function(from, action) { Ext.example.msg('保存成功', '添加级别成功!'); ds.load( { params : { start : 0, limit : 30, forumId : 4 } }); }, failure : function(form, action) { Ext.example.msg('保存失败', '添加级别失败!'); }, waitMsg : '正在保存数据,稍后...' }); dialog.hide(); } else { Ext.Msg.alert('信息', '请填写完成再提交!'); } } }, { text : '取消', handler : function() { newFormWin.hide(); } }] }); }); 5、 运行时的一些图(Firefox 2.0): 数据列表: 新建: 修改: 未选择数据行 选择数据行后,单击修改按钮(双击数据行可直接修改) 删除数据: 删除时确认 确认后删除数据: 源代码下载: 源代码下载: