最近在使用EasyUI1.4.2的DataGrid的过程中,发现了两个会二次加载的情况;
第一个是在页面初始化的时候,如果给datagrid指定了URL属性,而且pageNumber属性没有设置为1的时候,就会出现二次加载的情况。
第二个是条件查询的时候,填上条件之后,直接点击分页栏的左右按钮,这个时候,会产生两次请求,第一次请求是正常的带条件的请求,第二次请求是请求URL属性设置的地址,最后表格中的数据也是请求URL属性设置的地址返回的结果。
解决方案:
第一个问题比较好解决,将pageNumber设置为1就可以了,这个地方的原因如下:
在EasyUI1.4.2源码中的_612函数,这个函数的主要作用就是获取表格需要的数据,同步 DataGrid和Pagination的相关信息;
函数如下:
//data是表格的data,是getData函数的返回值
//_64b就是DataGrid对象
function _612(_64b,data){
var _64c=$.data(_64b,"datagrid");
var opts=_64c.options;
var dc=_64c.dc;
data=opts.loadFilter.call(_64b,data);
data.total=parseInt(data.total);
_64c.data=data;
if(data.footer){
_64c.footer=data.footer;
}
if(!opts.remoteSort&&opts.sortName){
var _64d=opts.sortName.split(",");
var _64e=opts.sortOrder.split(",");
data.rows.sort(function(r1,r2){
var r=0;
for(var i=0;i<_64d.length;i++){
var sn=_64d[i];
var so=_64e[i];
var col=_5e0(_64b,sn);
var _64f=col.sorter||function(a,b){
return a==b?0:(a>b?1:-1);
};
r=_64f(r1[sn],r2[sn])*(so=="asc"?1:-1);
if(r!=0){
return r;
}
}
return r;
});
}
if(opts.view.onBeforeRender){
opts.view.onBeforeRender.call(opts.view,_64b,data.rows);
}
opts.view.render.call(opts.view,_64b,dc.body2,false);
opts.view.render.call(opts.view,_64b,dc.body1,true);
if(opts.showFooter){
opts.view.renderFooter.call(opts.view,_64b,dc.footer2,false);
opts.view.renderFooter.call(opts.view,_64b,dc.footer1,true);
}
if(opts.view.onAfterRender){
opts.view.onAfterRender.call(opts.view,_64b);
}
_64c.ss.clean();
var _650=$(_64b).datagrid("getPager");
if(_650.length){
var _651=_650.pagination("options");
if(_651.total!=data.total){
//pagination的refresh就是用传入的参数对象的属性覆盖pagination对象的对应属性
_650.pagination("refresh",{total:data.total});
//opts是datagrid的属性,_651是pagination的options对象
if(opts.pageNumber!=_651.pageNumber&&_651.pageNumber>0){
opts.pageNumber=_651.pageNumber;
//_64b就是那个表格对象
_611(_64b);
}
}
}
_5af(_64b);
dc.body2.triggerHandler("scroll");
$(_64b).datagrid("setSelectionState");
$(_64b).datagrid("autoSizeColumn");
opts.onLoadSuccess.call(_64b,data);
};
原因就是pagination对象的pageNumber在表格第一次加载的时候,是1,DataGrid的pageNumber属性这个时候还是我们设置的属性,这两个属性在下面这段代码里同步,在这还没有同步:
if(opts.pageNumber!=_651.pageNumber&&_651.pageNumber>0){
opts.pageNumber=_651.pageNumber;
//_64b就是那个表格对象
_611(_64b);
}
在_611这个函数中,会再一次请求服务器,所以我们就是不让代码走进这个循环,也就是让opts.pageNumber==_651.pageNumber即可。
初次加载时。pagination的pageNumber属性是1,只要我们把DataGrid的pageNumber属性也设置为1,这样DataGrid初次加载的时候就不会二次请求了。
这里顺便看下_611函数:
/**_6e1是表格对象
* _6e2是queryParams
*/
function _611(_6e1,_6e2){
var opts=$.data(_6e1,"datagrid").options;
if(_6e2){
opts.queryParams=_6e2;
}
var _6e3=$.extend({},opts.queryParams);
if(opts.pagination){
$.extend(_6e3,{page:opts.pageNumber||1,rows:opts.pageSize});
}
if(opts.sortName){
$.extend(_6e3,{sort:opts.sortName,order:opts.sortOrder});
}
if(opts.onBeforeLoad.call(_6e1,_6e3)==false){
return;
}
$(_6e1).datagrid("loading");
//在这会请求一次服务器
var _6e4=opts.loader.call(_6e1,_6e3,function(data){
$(_6e1).datagrid("loaded");
$(_6e1).datagrid("loadData",data);
},function(){
$(_6e1).datagrid("loaded");
opts.onLoadError.apply(_6e1,arguments);
});
if(_6e4==false){
$(_6e1).datagrid("loaded");
}
};
总结一下:这个问题产生的原因是Pagination的pageNumber属性被初始化为1,如果DataGrid的pageNumber属性不设置为1,会导致代码进入_611函数,_611函数会再次请求服务器。这个地方要注意的就是设置DataGrid的pageNumber和Pagination的pageNumber初始化时的值一样,也就是1。
第二个问题其实是第一个问题一个放大的情况,还是下面这个判断的问题,举个例子,表格初始加载时,我们设置DataGrid的pageNumber属性为1,Pagination对象的属性初始化为1,这时,我们在条件输入框里输入条件,不去请求后台,获取分页需要的信息(其实就是data.total),直接点击分页栏的下一页按钮,请求服务器,返回数据,那么这时,Pagination的pageNumber是2,DataGrid的pageNumber是1,当代码走到下面这个判断的时候,两个条件都符合,就会又进入_611函数,再次请求服务器,那么我们看到传到_611函数的是表格对象,那么请求服务器的pageNumber肯定也是用的DataGrid的pageNumber属性,也就是这是二次请求请求的是无条件的第一页,数据返回来之后,DataGrid加载返回的无条件的第一页数据。那么我们不行执行_611函数的话,只要破坏这两个条件中的一个就可以,_651.pageNumber>0这个条件破坏不了,Pagination对象的pageNumber属性必须要是正的。那么我们就破坏第一个条件,让opts.pageNumber和_651.pageNumber在条件判断之前相等就可以了。
传入_611函数的是表格对象,很显然需要让Pagination对象的pageNumber属性等于DataGrid的pageNumber属性。那么在条件判断之前执行_651.pageNumber=opts.pageNumber;就可以了。
if(opts.pageNumber!=_651.pageNumber&&_651.pageNumber>0){
opts.pageNumber=_651.pageNumber;
//_64b就是那个表格对象
_611(_64b);
}
更精妙的做法是下面这样:
if(_651.total!=data.total){
//pagination的refresh就是用传入的参数对象的属性覆盖pagination对象的对应属性
_650.pagination("refresh",{**pageNumber:_651.pageNumber||opts.pageNumber**,total:data.total});
//opts是datagrid的属性,_651是pagination的options对象
if(opts.pageNumber!=_651.pageNumber&&_651.pageNumber>0){
opts.pageNumber=_651.pageNumber;
//_64b就是那个表格对象
_611(_64b);
}
}
顺便说下,如果先用条件查询服务器,在按分页栏上的上一页,下一页按钮的话,是没有这种情况的;输入条件-》点击查询-》点击上一页、下一页按钮,我们一般是使用这个流程,这个流程是没有问题的,上述情况只发生在输入条件-》点击上一页、下一页按钮,这样使用的时候。