上一篇中的最后一点提到了,如果在服务器端出现异常,没能完成预期的操作,那么客户端(浏览器)中的jqGrid还继续更新数据吗?
这一篇就来说说服务器端的操作。
首先看一下服务器端的代码,我将查看行数据和操作行数据放在了两个Action类里面:ViewContactAction和ContactConsoleAction。
说明:
- 因为客户端会和Server进行ajax交互,所以我在类里面加入了一个成员变量ajaxResult,用来保存操作实际的结果。当action产生json类型的result时,这个成员变量也会被串行化进json结果中,发送到客户端。客户端的javascript代码会解析这个值,以执行相应操作。
- 这两个类都是用了Object-backed Action的方式来传递数据(关于Object-backed Action可以参考《Struts2 in Action》一书的3.4节)。
在配置文件中,按如下配置Action:
说明:
- 请注意result的类型为json,而且includeProperties属性中包括ajaxResult这个成员变量名;
- 由于添加contact时,id属性值是由后台自动生成的,因此需要将这个值传回客户端作为Grid的行id值。
服务器端的代码似乎没有什么更多需要说明的地方了,应该一目了然。
下面看看客户端部分,这里面似乎有不少值得说明一下的部分。
首先看一下html的完整代码:
相比较之前的例子,这个例子最重要的变化是添加了一个id为consoleDlg的<div>块。在javascript的页面初始化部分我将使用jQuery UI的API将这个div生成为一个模态对话框,用作编辑数据的界面。
虽然jqGrid也提供了表单格式的编辑数据的界面,但是我个人感觉那个界面太基础,适用于简单的数据编辑情况,对于复杂的情况,可能还是自己写点代码更加灵活。
另一个项目中,我自己实现的相对复杂的表单界面:
回到本例中,上面的“对话框”div中,有一个form,其中有一个<input type="hidden" id="selectId"/>(当准备修改或者删除一行记录的时候,这行的id将被保存在这里,以备后用),以及若干个<input type="text">。
再来看看javascript部分,javascript部分主要功能分成几块:
- 初始化表格;
- 初始化对话框;
- 添加记录时打开对话框;
- 执行添加操作;
- 载入行数据到对话框;
- 修改记录时打开对话框;
- 执行修改操作;
- 删除记录时打开对话框;
- 执行删除操作。
先看一下完整代码,然后逐块分析:
1. 初始化Grid表格:
这一部分的代码,和上一篇中的例子完全相同,不再赘述。
2. 初始化对话框:
说明:
(1)处将modal属性设为true,即将对话框设置为“模态”,当对话框打开状态时,下层的Grid表格式不能被编辑的(注意z-Index的值);
(2)处为对话框添加了4个按钮,因为增、删、查都共用一个对话框,所以添加4个按钮是比较方便的,只要控制它们不同状态下的显隐状态就OK了。点击每个按钮都会执行各自对应的函数。
注:jQuery UI的dialog方法可以详细参考jQuery UI的文档。
3. 添加记录时打开对话框:
说明:
(1)处先获得对话框按钮的父元素;
(2)将所有的input元素解除disabled状态(在打开删除对话框时,会diable这些input元素);
(3)(4)处调整对话框按钮的显示隐藏状态;
(5)更新对话框标题。
4. 执行添加操作:
说明:
(1)从对话框的表单中读取各个输入项的值;
(2)在$.ajax()方法遇到error时,会提示错误(从而让jqGrid不再继续后面的Grid操作);
(3)如果$.ajax()成功,则执行回调函数,但是应当注意这里的“success”,是指ajax请求成功得到response,而不是Struts2 Action的“success”。当Action的result的name为“error”、“input”、“login”等的时候,只要它能够给客户端返回一个格式正确的json数据(我们这里定义了需要的是json),那么都会被认为是“success”;
(4)因此通过传回来的json数据中的ajaxResult项的值,来判断逻辑事务操作是否成功;(在正式项目中,我为不同的Action result定义了不同的ajaxResult值,以方便客户端判断,执行相应后续操作。这里为了演示简便,只定义了success一种,Action配置文件中也只定义了success结果,即使出现error或input等其他结果,Struts2也会因为找不到其他result配置,而抛出异常,也就不会向客户端发送json数据。客户端也就认为ajax请求失败了,从而执行$.ajax()中error项定义的回调方法。)
(5)如果执行成功,则根据Action配置文件的定义,json数据中会包括"contact.id":value这段数据;而jqGrid也就应该继续后续操作,更新Grid表格内的数据;
(6)获得最后选中行的行id;
(7)(8)如果最后选中行的行id不为null,则将新数据行插入到这行上面;否则将新数据加入到Grid的顶端;
(9)如果ajaxResult的值不为success,即逻辑实务操作没有成功,jqGrid不再进行后续操作,同时向用户提示操作失败。
5. 载入行数据到对话框:
当修改或者删除某行数据的时候,通常需要先打开这行记录,让用户看到并确认操作。这就需要将行数据载入到对话框中。
说明:
(1)如果没有行被选中,则提示用户;
(2)如果成功地从Server得到行数据,则将行数据的内容置入对话框表单中;
(3)根据新载入的数据将表格中的对应数据行一并更新一下;
(4)数据载入完毕后,打开对话框。
注:其实(3)是可选的部分,我的考虑是既然已经将最新的数据从Server取回来了,干脆就将Grid表格中的数据也更新一下。不论修改或删除操作是否被用户提交,更新一下数据总是好的,也不太费事。既然用户选择了这行数据,说明这行应该是用户关心的,有可能用户打开Grid页面一段时间了,而这行数据实际已经被其他用户更新了。当前用户通过打开对话框,也能得到最新的数据,即便没有修改或者删除,也不算无“功”而返啊。这主要也是从用户体验的角度出发。
6. 修改记录时打开对话框:
说明:
前几行的代码与添加记录是打开对话框时的过程相似,不再赘述;(1)处即在打开对话框之前,将对应行数据载入对话框。
7. 执行修改操作:
说明:参考执行添加操作的说明,这段应该很好理解。(1)处更新Grid中对应行的数据,并添加CSS样式。
8. 删除记录时打开对话框:
说明:(1)处将所有input全部disable掉,使之不能输入内容。
9. 执行删除操作:
以上就是实际应用中,使用自定义表单对话框编辑Grid数据的过程。下一篇说一下排序与搜索。