首页 > 代码库 > datagrid直接编辑保存的“设计缺陷”
datagrid直接编辑保存的“设计缺陷”
今天在使用easyUI的datagrid组件的时候,碰到了一些问题,记录下来以便下次快速解决。
需求是在一张表单里会关联有一个列表,可以增删查改
以前没用easyUI的时候,这个增和改的页面我一般是用一个dialog来做,保存之后再ajax传到列表里通过hidden来进行提交。
当然现在我也可以这么做,但是我想换种方式,因为easyUI的datagrid提供了直接在datagrid上编辑的功能(Row Editing in DataGrid)。
照着官网上的demo试了一下,也就是editor的应用,编辑倒是没问题,保存也OK
但是保存的时候是直接把value转换成text来保存的,这么一来的话,value的信息就消失了。比如说是一个combobox,那么保存完就只有text的信息了。
那在保存完之前总是能获取到value的,试了一下,第一想法是想从editor生成的input下手得到数据,毕竟用form来提交是最熟悉的方式啊,但是发现editor都没有指定name的地方(也许是我不知道),所以不好得到数据。既然不行,那么还是通过datagrid的getSelected方法来得到当前选中行(这里要先停止当前的编辑(endEdit)之后才能拿到填的数据)。
var row = $('#dispatches_details').datagrid('getSelected');
这里得到的row是一个json,且里面的combobox得到的都是value
到了这步,如果外层没有关联表单(也就新建一条就保存)的情况下,那么直接把row发到后台就可以保存了,之后显示就只需要text而不需要value的信息,这也许就是datagrid设计的初衷吧。但是它可能没有考虑到稍复杂的关联表单的情况,比如我们这里的业务,保存到数据库肯定是在外层表单提交的时候一起保存的,所以这个row的数据我们要暂时先记录下来。
怎么记录呢?在js里可能就只有array这种保存一串数据的数据类型了吧。于是创建了一个array(rows)来保存row
问题又来了,那么js中的array怎么传到后台呢?这也是困扰了我一个下午的问题。
我先是直接用{”rows”:rows}这样的格式post服务器,抓了HTTP请求,实际上发的请求参数是这样的{rows[0][a], rows[0][b],......rows[1][a], rows[1][b].......}其中a、b是row中的字段名
看到这种情况果断还很开心啊,以为Spring可以自动绑定参数了,百度了一下于是跑到服务器
写下一行代码:
public void saveDispatches(@RequestParam("rows[]") Ddetails ddetails[])
满心以为可以直接接到数据了,结果发现接不到。又试了
public void saveDispatches(@RequestParam("rows[][]") Object ddetails[][])都不行
最后直接request.getParameter(“rows[0][a]”)这样倒是有了,尼玛啊,这样接参数还不得接到死啊。
不过这种方式我也只是试试而已,js的array直接传递到后台肯定会有问题。
再一想,列表中的每一条记录最好都给一个name,然后value就是这条row(json类型)。比如说类似row1:””, row2:””, row3:””
想了一下觉得还是不可行,因为参数的数量不确定,后台没有一个好的方法来接参数
后来从form传数据得到灵感,可以用相同的名字,然后用分隔符分开,后台可以得到一个数组,但是这样其实后台得到的就是json的数据,没办法直接绑定参数到实体了。
但是这里还有一个问题,我发现json在作为array的一个元素的时候,HTTP请求过去的时候,不会自己转换成字符串,而是会以rows[a],row[b] 这种形式发送
这并不是我们想要的,于是先要把json转换成string类型:
$.extend({ toStr:function(json){ var str = ""; $.each(json, function(k,v){ str += "," + k + ':"' + v + '"'; }); str = "{" + str.substring(1) + "}"; return str; } })
接下来表单提交的时候,就可以这么传数据:
$("#dispatches_form").form('submit', { url:'repairs/saveDispatches', onSubmit: function(param){ param.ddetails = jsonArr.join('@'); }, success:function(data){ $.messager.progress('close'); $("#repairsPaper").dialog('close'); } });
这样后台就能接到json格式的字符串了,再通过“@”分开成一条条json记录,接下来
就需要我们手动绑定到实体了,为了防止还有这种需求,于是写了一个还算通用的将json和实体绑定的方法:
public static <T> T transferFromJsonObject(Class<T> clazz, JSONObject jsonObject) { T t = null; try { t = clazz.newInstance(); Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); Object value; if ((value = http://www.mamicode.com/jsonObject.get(field.getName())) != null>至此,虽然过程比较曲折,但是总算搞定了~