在封装的主从表模板代码中,从表添加多条数据时,最后的修改数据总是会覆盖掉前面添加的数据,这个bug存在很久了,一直没有找到具体原因,昨天刚好有小伙伴急切需要解决这个bug,所以今天有重新排查了一遍代码,功夫不负有心人,终于找到具体原因了,其实就是js对象的问题,因为之前是用了一个对象传递,push进去列表的都是同一个对象,所以属性值会被覆盖。知道了原因,那么解决的办法也就简单了,就是克隆传进来的对象。

原来的代码:
![1_20211202153633101.png 58K155)BZ]89}8U4%6$NMQN.png](/upload/img/share/0/1_20211202153633101.png)
修复代码:

//添加行
function addRow(config,editTableData,rowData){
$("#"+config.addBtnId).unbind("click");
$("#"+config.addBtnId).click(function (){
editTableData.push(rowData);
layui.table.reload(config.tableId,{
data:editTableData // 将新数据重新载入表格
});
});
}
// 保存数据
function saveData(config,editTableData){
$("#"+config.saveBtnId).unbind("click");
$("#"+config.saveBtnId).click(function (){
if(editTableData.length>0)
submitData(config.saveUrl,{"tableList":JSON.stringify(editTableData)});
});
}
// 删除多行
function deleteRows(config,editTableData){
$("#"+config.delBtnId).unbind("click");
$("#"+config.delBtnId).click(function (){
var checkStatus = layui.table.checkStatus(config.tableId);
if(checkStatus.data.length>0){
var confirmIndex = layer.confirm('您确定要删除吗?',{btn: ['确定', '取消'],title:"提示"}, function(){
var ids = [];
var newTableData=new Array();
$.each(editTableData,function(i,obj){
var checked=obj["LAY_CHECKED"];
var id=obj[config.dataId];
if(checked==true){
if(id){
ids.push(id);
}
}else{
newTableData.push(obj);
}
});
// 向服务端发送删除指令
if(ids.length>0)
deleteData(config.deleteUrl,ids);
editTableData=newTableData;
layui.table.reload(config.tableId,{data:editTableData}); // 重新渲染表格
layer.close(confirmIndex); // 关闭弹窗
});
}else{
layer.alert('请选择行',{icon: 7});
}
});
}
//克隆对象
function clone(obj){
var buf;
if(obj instanceof Array){
buf=[];
var i=obj.length;
while(i--){
buf=clone(obj[i]);
}
return buf;
}
else if(obj instanceof Object){
buf={};
for(var key in obj){
buf[key]=clone(obj[key]);
}
return buf;
}else{
return obj;
}
}这样就完美解决了这个问题。优化了代码之后,在页面可以覆盖重写layui的done回调函数,然后把原来的done里面的代码copy出来即可。
项目:
JFinal-layui-pro


