3.1、ExtJS完成添加,修改和删除功能
首先,完成修改操作。
在GridPanel中,加入一个插件,实现可编辑的功能
// 建立表格面版 var panel = Ext.create('Ext.grid.Panel', { title : '城市列表', store : s, // 表格的数据(具体的表格内容) columns : [{ header : '城市编号', // 表头 dataIndex : 'id',// 这一列要加入的数据内容 width : 100 }, { header : '省份编号', dataIndex : 'upid', width : 100 }, { header : '城市名称', dataIndex : 'title', width : 195, field : { // 编辑框 xtype : 'textfield', allowBlank : false } }], plugins : [Ext.create('Ext.grid.plugin.CellEditing', { // 允许对单元格进行编辑 clicksToEdit : 2 // 编辑时的点击次数,这里表示双击单元格后可以编辑。 })], bbar : pageBar, // 设置底部工具条,如果想使用顶部,可以通过tbar属性来完成。 width : 400, autoHeight : true, // 根据表格内容,自动调整高度 renderTo : "testDiv" }); |
这里无法修改数据库,因此需要先在DAO中将修改方法完成。
在js里加入一个提交按钮,以便完成数据库的提交操作。
// 定义一个提交按钮 var submitBtn = Ext.create("Ext.button.Button",{ text : "提交" });
// 建立分页工具条 var pageBar = Ext.create("Ext.toolbar.Paging", { pageSize : 5, store : s , items : ["-",submitBtn] }); |
加入提交按钮的事件,判断哪条数据被修改了,如果被修改了,就提交到后台进行数据库的修改。
// 事件 submitBtn.on("click", function(btn, e, obj) { // 取得数据中被修改的数据 for (var i = 0; i < s.getCount(); i++) { var model = s.getAt(i); // 判断是否被修改 if (model.isModified("title")) { // 取得id,upid和title,提交到后台,完成数据库操作 var id = model.get("id"); var upid = model.get("upid"); var title = model.get("title");
// 提交数据也需要使用AJAX完成。 Ext.Ajax.request({ url : 'areaplus.do', params : { "areaplus.id" : id, "areaplus.upid" : upid, "areaplus.title" : title, status : "update" }, success : function(xmlHttp) { // 后台没有提示异常,进入success // 重新加载一次当前数据,可以取消被编辑的标记 s.reload(); } , failure: function(xmlHttp) { Ext.MessageBox.alert("警告","修改失败,出现错误,错误代码:" + xmlHttp.status); } }); } } }); |
在Action中完成数据库操作。
public ActionForward update(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { AreaplusForm areaplusForm = (AreaplusForm) form;
// 调用修改操作 service.update(areaplusForm.getAreaplus());
return null; } |
这里只是修改了title,如果想一起修改upid,应该在upid的列中也加入一个修改的field,但这个field要使用下拉列表完成。
var comboS = Ext.create('Ext.data.Store', { fields : ['id', 'title'], proxy : { type : 'ajax', url : 'areaplus.do?status=listArea', // 取得数据的路径 reader : { type : 'json', // 返回的类型,一般都使用json root : 'allArea' // 作为返回列表数据的属性名 } } });
// 声明一个所有省份的下拉列表,以便修改upid时使用 var combo = Ext.create('Ext.form.field.ComboBox', { displayField : 'title', // 显示文字所对应的属性名 valueField : "id", // 作为value的属性名 store : comboS, // 使用的数据 queryMode : 'remote', // 数据来源(远程remote或本地local) typeAhead : true // 是否可以自动选中和提示 }); |
将这个combo设置为upid的编辑框
// 建立表格面版 var panel = Ext.create('Ext.grid.Panel', { title : '城市列表', store : s, // 表格的数据(具体的表格内容) columns : [{ header : '城市编号', // 表头 dataIndex : 'id',// 这一列要加入的数据内容 width : 100 }, { header : '省份编号', dataIndex : 'upid', width : 100 , field : combo }, { header : '城市名称', dataIndex : 'title', width : 195, field : { xtype : 'textfield', allowBlank : false } }], plugins : [Ext.create('Ext.grid.plugin.CellEditing', { // 允许对单元格进行编辑 clicksToEdit : 2 })], bbar : pageBar, // 设置底部工具条,如果想使用顶部,可以通过tbar属性来完成。 width : 400, autoHeight : true, // 根据表格内容,自动调整高度 renderTo : "testDiv" }); |
Action中完成listArea方法,也要拼写JSON数据。
public ActionForward listArea(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { AreaplusForm areaplusForm = (AreaplusForm) form;
List<Area> allArea = service.listArea();
// 准备JSON格式数据 JSONObject root = new JSONObject(); JSONArray array = new JSONArray();
if (allArea.size() > 0) { Iterator<Area> iter = allArea.iterator(); while (iter.hasNext()) { Area area = iter.next(); JSONObject obj = new JSONObject(); obj.put("id", area.getId()); obj.put("title", area.getTitle());
array.put(obj); } } root.put("allArea", array);
response.setCharacterEncoding("GBK"); response.setContentType("text/html");
PrintWriter out = response.getWriter(); out.print(root); out.close();
return null; } |
最后,在提交时,判断如果upid被修改也要提交
// 事件 submitBtn.on("click", function(btn, e, obj) { // 取得数据中被修改的数据 for (var i = 0; i < s.getCount(); i++) { var model = s.getAt(i); // 判断是否被修改 if (model.isModified("title") || model.isModified("upid")) { // 取得id,upid和title,提交到后台,完成数据库操作 var id = model.get("id"); var upid = model.get("upid"); var title = model.get("title");
// 提交数据也需要使用AJAX完成。 Ext.Ajax.request({ url : 'areaplus.do', params : { "areaplus.id" : id, "areaplus.upid" : upid, "areaplus.title" : title, status : "update" }, success : function(xmlHttp) { // 后台没有提示异常,进入success // 重新加载一次当前数据,可以取消被编辑的标记 s.load(); }, failure : function(xmlHttp) { Ext.MessageBox.alert("警告", "修改失败,出现错误,错误代码:" + xmlHttp.status); } }); } } }); |
实现添加功能,再在js中声明一个添加按钮,点此按钮后,表格中多出一个新的行,并自动编辑该行的title值。
// 定义一个添加按钮 var addBtn = Ext.create("Ext.button.Button", { text : "添加" });
// 建立分页工具条 var pageBar = Ext.create("Ext.toolbar.Paging", { pageSize : 5, store : s, items : ["-",addBtn,"-",submitBtn] });
|
加入监听,当点按钮时,为表格多建立一个新的行
addBtn.on("click", function(btn, e, obj) {
var a = Ext.create("Areaplus", { id : "", upid : 1, title : "" }); s.add(a); // 自动开始编辑最后一条数据 cellEditing.startEditByPosition({ row : s.getCount() - 1, column : 2 }); }); |
需要先声明出Areaplus对象
// 声明一行数据对应的对象 Ext.define('Areaplus', { extend : 'Ext.data.Model', fields : [{ name : 'id', type : 'string' }, { name : 'upid', type : 'integer' }, { name : 'title', type : 'string' }] }); |
还要将单元格编辑器单独取出,使用
// 定义编辑插件 var cellEditing = Ext.create('Ext.grid.plugin.CellEditing', { // 允许对单元格进行编辑 clicksToEdit : 2 })
// 建立表格面版 var panel = Ext.create('Ext.grid.Panel', { title : '城市列表', store : s, // 表格的数据(具体的表格内容) columns : [{ header : '城市编号', // 表头 dataIndex : 'id',// 这一列要加入的数据内容 width : 100 }, { header : '省份编号', dataIndex : 'upid', width : 100, field : combo }, { header : '城市名称', dataIndex : 'title', width : 195, field : { xtype : 'textfield', allowBlank : false , emptyText : "请输入城市名称" } }], plugins : [cellEditing], bbar : pageBar, // 设置底部工具条,如果想使用顶部,可以通过tbar属性来完成。 width : 400, autoHeight : true, // 根据表格内容,自动调整高度 renderTo : "testDiv" }); |
最后加入删除功能。
需要在程序中再加入一个删除按钮,点此按钮后弹出确认框,当点确定后,取得该行的id值,传递到后台,完成删除操作。
delBtn.on("click", function(btn, e, obj) { // 取得当前store中选中的行 var sm = panel.getSelectionModel(); cellEditing.cancelEdit(); // 打印此数据测试 // Ext.MessageBox.alert("提示",sm.getSelection()[0].get("title")); // 弹出提示 Ext.MessageBox.confirm("提示", "确定要删除该数据(" + sm.getSelection()[0].get("title") + ")吗?", function(btn) { // 点击后的回调 if (btn == "yes") { // 删除 var id = sm.getSelection()[0].get("id");
Ext.Ajax.request({ url : 'areaplus.do', params : { "areaplus.id" : id, status : "delete" }, success : function(xmlHttp) { // 后台没有提示异常,进入success // 重新加载一次当前数据,可以取消被编辑的标记 s.remove(sm.getSelection()); }, failure : function(xmlHttp) { Ext.MessageBox.alert("警告", "删除失败,出现错误,错误代码:" + xmlHttp.status); } }); } }); }); |
Action中加入删除方法
public ActionForward delete(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { AreaplusForm areaplusForm = (AreaplusForm) form;
// 调用修改操作 service.delete(areaplusForm.getAreaplus().getId());
return null; } |
还可以在表格面版中加入一个监听,以便修改删除按钮是否可用。
// 定义一个删除按钮 var delBtn = Ext.create("Ext.button.Button", { text : "删除", disabled : true });
// 建立表格面版 var panel = Ext.create('Ext.grid.Panel', { title : '城市列表', store : s, // 表格的数据(具体的表格内容) columns : [{ header : '城市编号', // 表头 dataIndex : 'id',// 这一列要加入的数据内容 width : 100 }, { header : '省份编号', dataIndex : 'upid', width : 100, field : combo }, { header : '城市名称', dataIndex : 'title', width : 195, field : { xtype : 'textfield', allowBlank : false, emptyText : "请输入城市名称" } }], plugins : [cellEditing], bbar : pageBar, // 设置底部工具条,如果想使用顶部,可以通过tbar属性来完成。 width : 400, autoHeight : true, // 根据表格内容,自动调整高度 listeners: { 'selectionchange': function(view, records) { delBtn.setDisabled(!records.length); } }, renderTo : "testDiv" }); |
3.2、Ext中的表单处理
使用ExtJS提供的FormPanel以及里面的表单元素可以创建表单,表单中的元素支持自动验证以及自动提示错误信息的功能。
Ext.onReady(function() { var img = Ext.create('Ext.Img', { src : 'image.jsp' , renderTo: "codeDiv" , floating : true, x : 280 , y : 140 });
var panel = Ext.create('Ext.form.Panel', { title : '普通表单', bodyPadding : 5, width : 350, floating : true, x : 0, y : 0,
// 设置表单提交路径,但提交时,也是AJAX形式提交 url : 'areaplus.do?status=insert', defaultType : 'textfield', // 设置表单元素的默认类型,这里设置为文本框 items : [{ fieldLabel : '用户名', // 文字说明 name : 'user.userid', // 参数名 allowBlank : false,// 是否允许为空 blankText : "请输入用户名", minLength : 6, maxLength : 16, minLengthText : "用户名长度不能少于 6 位", maxLengthText : "用户名长度不能超过 16 位" }, { fieldLabel : '密码', name : 'user.password', inputType : "password", // 输入类型,可以改为password。 allowBlank : false }, { fieldLabel : '邮件地址', name : 'user.email', allowBlank : false }, { fieldLabel : '生日', name : 'user.birthday', xtype : "datefield", format : "Y-m-d" },{ fieldLabel : '验证码', name : 'code', allowBlank : false }], buttonAlign : "center", buttons : [{ text : '提交', formBind : true, handler : function() { var form = panel.getForm(); if (form.isValid()) { form.submit({ success : function(form, action) { Ext.Msg.alert('Success', action.result.msg); }, failure : function(form, action) { Ext.Msg.alert('Failed', action.result.msg); } }); } } }, { text : '重置', handler : function() { panel.getForm().reset(); } }], renderTo : "testDiv" });
}); |
3.3、树型列表
树型列表如果想实现多级菜单的功能,需要在数据库中建立一张与自己关联的菜单表(权限表)
CREATE TABLE menu ( id int primary key auto_increment , upid int , title varchar(50) , url text , leaf int /* 0 不是叶子节点,可以展开,1是叶子,不能展开 */ );
INSERT INTO menu (upid,title,url,leaf) VALUES (0,'商品管理',null,0), (0,'订单管理',null,0), (0,'用户管理',null,0), (0,'系统管理',null,0), (1,'发布商品','product_insert.jsp',1), (1,'商品列表','product_list.jsp',1), (2,'审核订单','order_list.jsp',1), (2,'退换货管理',null,0), (8,'退货列表','tui.jsp',1), (8,'换货列表','huan.jsp',1), (3,'用户列表','member_list.jsp',1), (4,'管理员管理','admin.jsp',1), (4,'角色管理','role.jsp',1);
|
还需要完成其DAO操作,只需要一个方法
@Component public class MenuDAOImpl extends HibernateDaoSupport implements IMenuDAO {
@Autowired public MenuDAOImpl(HibernateTemplate hibernateTemplate) { super.setHibernateTemplate(hibernateTemplate); }
public List<Menu> findByUpid(int upid) throws Exception { String hql = "FROM Menu AS m WHERE m.upid = ?"; return super.getHibernateTemplate().find(hql, upid); }
} |
通过Store远程取得数据
Ext.onReady(function() { var store = Ext.create('Ext.data.TreeStore', { proxy: { type: 'ajax', url: 'areaplus.do?status=showMenuPlus', reader: { type : "json" , root : "allMenu" } }, root : { id : "0" , text : "后台管理" } });
var tree = Ext.create('Ext.tree.Panel', { store : store, rootVisible : true, height : 600, width : 300, title : '树型列表', renderTo : 'testDiv' });
}); |
后台需要完成查询,并拼写出JSON格式数据。
public ActionForward showMenuPlus(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { AreaplusForm areaplusForm = (AreaplusForm) form;
// 查询 List<Menu> allMenu = service.showMenuPlus(areaplusForm.getNode());
// 准备JSON格式数据 JSONObject root = new JSONObject(); JSONArray array = new JSONArray();
if (allMenu.size() > 0) { Iterator<Menu> iter = allMenu.iterator(); while (iter.hasNext()) { Menu m = iter.next(); JSONObject obj = new JSONObject(); obj.put("id", m.getId()); obj.put("text", m.getTitle()); // 是否要加入超连接 if (m.getUrl() != null) { obj.put("href", m.getUrl()); } obj.put("leaf", m.getLeaf() == 1);
array.put(obj); } } root.put("allMenu", array);
response.setCharacterEncoding("GBK"); response.setContentType("text/html");
PrintWriter out = response.getWriter(); out.print(root); out.close();
return null; } |
3.4、Struts2概述
Struts2是由Apache推出的,是在Struts1的基础上结合了WebWork项目的架构,来实现的新的MVC功能。
Struts2的主要配置架构是WebWork,其中加入了一点Struts1的特性。
由于也是MVC框架,因此也要将项目分为三个部分:
1) Model层仍然使用之前的Spring + Hibernate或JDBC等技术。
2) View层中将Struts1原有的三个标签库取消,改为新的s标签。
3) Control层中原本是ActionForm + Action,现在合并成为只有Action。
Struts1的工作原理:
jsp à ActionServlet(*.do,读取struts-config.xml)à ActionForm(接收参数,验证)
à 通过 à Action à forward(struts-config.xml)
à 不通过 à 返回input (struts-config.xml)
Struts2的工作原理:
jsp à Filter(/*,读取struts.xml,struts.properties) à Action(接收参数,验证)
à 通过 à execute à result(struts.xml)
à 不通过 à 返回input(struts.xml)
Struts1和Struts2的区别:
1) Struts1是由Apache自己完成的,Struts2是WebWork框架基础上修改的
2) 因此两者的作用都是MVC框架,但配置和代码的编写方式,以及使用的类库完全不同。