layui中table组件功能增强及优化
《layui中table组件内存占用不断上升问题》在这篇文章中提到了table组件内存占用问题。今天给出自己的优化方式。那篇文章已经提到了问题的核心。重复调用render()方法,该方法是一个全过程方法,包括配置的解析处理,组件的框架渲染,各组成部分的渲染,数据的填充等等。在重复调用时,大量的中间数据、对象没有及时释放导致内存一直上升。实际应用中是完全不需要每次全过程的构建。只需要重新...
《layui中table组件内存占用不断上升问题》在这篇文章中提到了table组件内存占用问题。今天给出自己的优化方式。那篇文章已经提到了问题的核心。重复调用render()方法,该方法是一个全过程方法,包括配置的解析处理,组件的框架渲染,各组成部分的渲染,数据的填充等等。在重复调用时,大量的中间数据、对象没有及时释放导致内存一直上升。实际应用中是完全不需要每次全过程的构建。只需要重新获取数据,更新部分相关ui部分,如:页码,记录总数等等。
查看源码,可以看到获取数据有单独的方法:pullData。那么在执行页面查询、及刷新时,只需要调用该方法即可。
在table模块中增加如下接口:
//表格加载
table.query=function(id,param){
var config = getThisTableConfig(id); //获取当前实例配置项
if(!config) return;
var that = thisTable.that[id];
that.config = $.extend(true, {}, that.config, {where:param});
that.page=1;
that.pullData(that.page);
};
//表格刷新
table.refresh=function(id){
var config = getThisTableConfig(id); //获取当前实例配置项
if(!config) return;
var that = thisTable.that[id];
that.pullData(that.page);
};
两者的区别就是,查询需要传入新的查询条件,同时将页面设置为1;而刷新不需要设置任何东西,只是单纯的重新获取一次数据。
第二点说下table表格的编辑功能。设置了编辑功能后,就可以直接在table中的单元格中编辑数据。并且原组件提供了一个编辑过程中的事件:单元格编辑时的change事件。这是一个内部事件处理。在这处理过程中对外提供了一个接口 edit(filter) 可以让用户进行再处理。但在 edit(filter)调用前,已经将输入值设置到内部数据对象了。即这个对外接口已经无法影响编辑值了。而实际应用中更合理的情况是,在外部接口中会对数据进行校验,根据校验结果来决定是否将编辑值写入内部数据对象。说到校验好像table的编辑功能还没有校验功能。需要自己增强该功能。
既然要加校验,一般情况是编辑完了,再进行校验,校验通过了,新值才能写入内部数据对象同时界面也显示新值。有些情况下可以边输入值边校验,如只能输入整数。非整数可以即时校验及时清除。但有些则不行,如小数。输入小数点的时候,应该是合法的,可如果输入了小数点后就不再输入。有不是一个有效数字。这是即时校验不好处理的。所以还不如统一放在输入完成后进行校验。也就是blur事件中。
原组件有blur事件处理,是内部处理。没有对外提供接口。因此可以把change事件中的对外接口关闭,在blur中增加对外接口。
//单元格编辑
that.layBody.on('input', '.'+ELEM_EDIT, function(){ //change
var othis = $(this)
,value = this.value
,field = othis.parent().data('field')
,key=othis.parent().data('key')
,col=that.getColsConfig(parseInt((key.split('-'))[2]))
,index = othis.parents('tr').eq(0).data('index')
,data = table.cache[that.key][index];
//data[field] = value; //更新缓存中的值
var callRtn=layui.event.call(this, MOD_NAME, 'edit('+ filter +')', commonMember.call(this, {
value: value
,field: field
,col:col
}));
}).on('blur', '.'+ELEM_EDIT, function(){
var templet
,othis = $(this)
,value = this.value
,thisElem = this
,field = othis.parent().data('field')
,key=othis.parent().data('key')
,col=that.getColsConfig(parseInt((key.split('-'))[2]))
,index = othis.parents('tr').eq(0).data('index')
,data = table.cache[that.key][index];
//add 2020.4.10
var callRtn=layui.event.call(this, MOD_NAME, 'afterEdit('+ filter +')', commonMember.call(this, {
value: value
,field: field
,col:col
}));
if(callRtn!=null&&callRtn==false){
return;
}
data[field] = value; //更新缓存中的值
afterEdit就是我们新增加的对外接口,原edit对外接口没有关闭先留着。同时数据对象的更新也是放在afterEdit之后。且是根据对外接口的结果值来控制的。这为校验提供了条件。
还差一个条件。校验需要校验规则。校验规则如何配置?很自然配置在列配置对象中好理解。
width:150,align:'right',edit:'text',error:'应为整数',dataType:'Number'},
列配置是组件的入口,是一个很好的扩展点。
现在需要回调接口:afterEdit中来获取校验规则。原组件在调用回调方法时,主要传入当前编辑数据,tr对象之类。没有列配置对象。所以这是一个需要我们修改的地方
,col=that.getColsConfig(parseInt((key.split('-'))[2]))
var callRtn=layui.event.call(this, MOD_NAME, 'afterEdit('+ filter +')', commonMember.call(this, {
value: value
,field: field
,col:col
}));
在到回调方法中应用规则
table.on('afterEdit(tab-car-run)', function(obj){
var col=obj.col
,tr=obj.tr
,td=$(tr).find("td[data-field='"+obj.field+"']");
var rst=validator.validate(obj.value,col.require,col.dataType);
if(!rst){
layer.tips(col.error||'数据格式不正确', td,{tips: 3});
}
return rst;
});
还有一个增强的地方:编辑按数据后,需要知道哪些行的数据是被编辑过。这样做保存数据到后台时,更方便。而不是将所有数据都覆盖式的保存。
还有其他组件也有优化和增强的地方,以后细说。感觉这套组件缺乏实际项目的锤炼。简单应用可能没什么问题,大点的应用要有采坑的准备和填坑的能力
更多推荐
所有评论(0)