需求
最近用到edatagrid这个扩展,但是由于后台框架限制,接收的参数有特殊格式,需要在增删改的时候格式化参数,但是仔细研究了API之后发现没有对应的方法,于是乎决定扩展一点功能
分析
修改插件源码似乎不是什么好办法,但是如果保持原有用法不变,只是扩展一些用法的话应该问题不大,毕竟是兼容的方法,所以我决定从源码入手,扩展一下
实现
首先考虑了增加参数,但是增加参数的话需要分别为增删改加上一个paramFormater函数,这样就增加了记忆的负担,而且相关性很差,所以我决定扩展三个url,实现步骤如下
- 如果url是字符串则保持原有逻辑
- 如果url是对象,则 url = url.url,发送的参数修改为 url.paramFormater(row) 的返回值
代码如下
增加和修改的逻辑都在onAfterEdit函数中,修改onAfterEdit函数如下:
onAfterEdit: function(index, row){
delAutoGrid(this);
opts.editIndex = -1;
var url = row.isNewRecord ? opts.saveUrl : opts.updateUrl;
if (url){
var changed = false;
var fields = $(this).edatagrid('getColumnFields',true).concat($(this).edatagrid('getColumnFields'));
for(var i=0; i<fields.length; i++){
var field = fields[i];
var col = $(this).edatagrid('getColumnOption', field);
if (col.editor && opts.originalRow[field] != row[field]){
changed = true;
break;
}
}
if (changed){
//根据url类型修改了参数
if (typeof url === "object" && $.isFunction(url.paramFormater)){
row = url.paramFormater.call(null,row,opts.originalRow);
url = url.url;
}
$.post(url, row, function(data){
if (data.isError){
$(target).edatagrid('cancelRow',index);
$(target).edatagrid('selectRow',index);
$(target).edatagrid('editRow',index);
opts.onError.call(target, index, data);
return;
}
data.isNewRecord = null;
$(target).datagrid('updateRow', {
index: index,
row: data
});
if (opts.tree){
var idValue = row[opts.idField||'id'];
var t = $(opts.tree);
var node = t.tree('find', idValue);
if (node){
node.text = row[opts.treeTextField];
t.tree('update', node);
} else {
var pnode = t.tree('find', row[opts.treeParentField]);
t.tree('append', {
parent: (pnode ? pnode.target : null),
data: [{id:idValue,text:row[opts.treeTextField]}]
});
}
}
opts.onSuccess.call(target, index, row);
opts.onSave.call(target, index, row);
},'json');
} else {
opts.onSave.call(target, index, row);
}
} else {
opts.onSave.call(target, index, row);
}
if (opts.onAfterEdit) opts.onAfterEdit.call(target, index, row);
},
删除的逻辑在 _del函数中,其中多行删除的逻辑是一行一行的调用_del函数,这个逻辑很是坑爹,但是暂时还可以满足我的需求,所以就没有修改它,只是在url上做了扩展,可以发送自定义参数,这样对于联合主键的表来说会方便不少,_del函数修改如下
function _del(row){
var index = dg.datagrid('getRowIndex', row);
if (index == -1){return}
if (row.isNewRecord){
dg.datagrid('cancelEdit', index);
} else {
//修改了这里的代码
var url = opts.destroyUrl;
if (url){
//修正了参数
var idValue = row[opts.idField||'id'];
var param = {id:idValue};
if (typeof url === "object" && $.isFunction(url.paramFormater)){
param = url.paramFormater.call(null,row,opts.originalRow);
url = url.url;
}
$.post(url, param , function(data){
var index = dg.datagrid('getRowIndex', idValue);
if (data.isError){
dg.datagrid('selectRow', index);
opts.onError.call(dg[0], index, data);
return;
}
if (opts.tree){
dg.datagrid('reload');
var t = $(opts.tree);
var node = t.tree('find', idValue);
if (node){
t.tree('remove', node.target);
}
} else {
dg.datagrid('cancelEdit', index);
dg.datagrid('deleteRow', index);
}
opts.onDestroy.call(dg[0], index, row);
var pager = dg.datagrid('getPager');
if (pager.length && !dg.datagrid('getRows').length){
dg.datagrid('options').pageNumber = pager.pagination('options').pageNumber;
dg.datagrid('reload');
}
}, 'json');
} else {
dg.datagrid('cancelEdit', index);
dg.datagrid('deleteRow', index);
opts.onDestroy.call(dg[0], index, row);
}
}
}
修改后的API
用法和原来保持一致,如果原来有页面依赖这个插件,完全不用改动代码
新增用法:
参数 | 类型 | 介绍 | 默认值 |
---|---|---|---|
saveUrl | string/object | A URL to save data to server and return the added row. | null |
updateUrl | string/object | A URL to update data to server and return the updated row. | null |
destroyUrl | string/object | A URL to post 'id' parameter to server to destroy that row. | null |
示例:
//以saveUrl做例子,这里配置了url,paramFormater函数接收两个参数row和oldrow,为当前需要保存的行数据以及原来的数据.
//为row加上了自己的数据,当然,这里可以返回任意你想要发送的数据,都很方便
//updateUrl和destroyUrl也同样做了扩展,可以方便的发送自己想要的数据
saveUrl:{
url:"savadata.php",
paramFormater: function(row,oldrow){
row.mydata = "mydata";
return row;
}
}
写在最后
希望这点小小的改动可以帮到大家下面是我改好的插件,放在了百度云盘了,如果有需要可以直接下载覆盖原来的插件就可以用了,不会影响原来的功能
点击下载(百度云盘)
后记
在使用过程中又发现了一个问题,就是有时候需要原来的数据做一些处理,还好插件里已经记录了下来,我们只需要在调用paramFormater的时候加上这个参数就可以了,所以我又修改了一下代码
PS:文章里的代码改了,百度云盘的文件没有更新,如果需要自己改一下,只是在call的时候加一个参数