表格分页在网站类系统中,是一个很常见的功能,由于用的是jQuery EasyUI插件,所以采用DataGrid数据表格来实现。很明显,加载分页是通过js代码配合jQuery EasyUI插件来实现的,所以先列出视图和控制器中的大致代码吧。
视图代码很简单,一个table显示分页:
<!-- 日志列表 -->
<div id="operLogTable" style="width:100%;">
<table class="easyui-datagrid" id="operLogList"
data-options="singleSelect:true,
height:400,animate:true,collapsible:true,fitColumns:true,rownumbers:true,
pagination:true,pageNumber:1,pageSize:100,pageList:[100],
toolbar:''">
<thead>
<tr>
<th data-options="field:'id',hidden:true"></th>
<th data-options="field:'logType',align:'center',width:100,formatter:logTypeFormat">日志类型</th>
<th data-options="field:'operTime',align:'center',width:100">操作时间</th>
<th data-options="field:'operation',align:'center',width:150">操作内容</th>
<th data-options="field:'result',align:'center',width:100,formatter:resultFormat">操作结果</th>
<th data-options="field:'description',align:'center',width:100">操作描述</th>
<th data-options="field:'executor',align:'center',width:100">操作者</th>
</tr>
</thead>
</table>
</div>
然后是控制器代码:
/**
* 查询日志
* @param logType 日志类型
* @param operation 操作类型
* @param result 运行结果
* @param executor 执行者
* @param beginTime 开始时间
* @param endTime 结束时间
* @param page 分页显示第几页
* @param rows 单页显示多少行
* @return
*/
@RequestMapping(value="/queryOperLog")
@ResponseBody
public Map<String,Object> queryOperLog(
@RequestParam("logType") Short logType,
@RequestParam("operation") String operation,
@RequestParam("result") Short result,
@RequestParam("executor") String executor,
@RequestParam("beginTime") String beginTime,
@RequestParam("endTime") String endTime,
@RequestParam("page") Integer page,
@RequestParam("rows") Integer rows){
List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
Map<String,Object> reMap = new HashMap<String,Object>();
int total = 0;
…… //省略给日志结果列表list赋值的具体代码
reMap.put("total", total);//total是返回条件查询后的数量
reMap.put("rows", list);//rows这里是返回条件查询后的结果集,跟上面参数传递总的rows含义不同
return reMap;
}
最后,通常的做法是,页面通过一个查询按钮,触发js函数,调用该控制器取得数据后,回调显示到页面上,从而实现分页,代码如下:
/**
* 查询操作日志
*/
function queryOperLog(){
$.post(getUrl()+"/queryOperLog.do",$("#queryCondition").serialize(),function(data){
if(null != data && 0 != data.length){
$("#operLogList").datagrid('loadData',data);
}else{
alert("没有数据!");
}
});
}
上面的列表是通过datagrid方法来进行分页显示的,这个可以查看jQuery EasyUI的开发文档。问题的关键点在于,上面这种方式,传递调用控制器中queryOperLog方法时,该方法无法获取参数page和rows,因为这是页面中分页栏的内容,$("#queryCondition").serialize()里面并不包含此类参数。
为何不包含此类参数?因为我们调用jquery中的post方法,只认方法名后的参数,这里是$("#queryCondition").serialize(),而元素queryCondition在列表上面(通常会这样设计,上面的视图代码没有体现出来),或者查询窗体里面,并不包含列表所在表格,自然也不包办列表所在表格里面分页栏中内容。
所以,会导致调用后台控制器中queryOperLog方法失败,显示没有参数page。那通过js获取分页栏上的page和rows,添加到参数后面不就可以了吗,修改以上代码如下:
/**
* 查询操作日志
*/
function queryOperLog(){
var page=$(".pagination-num").val(); //获取分页栏上显示的第几页
var rows=$(".pagination-page-list").val(); //获取分页栏上单页显示多少行
$.post(getUrl()+"/queryOperLog.do",$("#queryCondition").serialize()+"&page="+page+"&rows="+rows,function(data){
if(null != data && 0 != data.length){
$("#operLogList").datagrid('loadData',data);
}else{
alert("没有数据!");
}
});
}
这种方式好像也可以,但问题在于,我们的js函数是通过点击页面的查询按钮触发的,如果查询结果为1000行,而我们单页显示设置的为100行,这个时候,我们点击分页栏上的下一页按钮,是不会进行分页跳转加载的。除非我们补上一个操作,这个时候再点击一下页面的“查询”按钮,参数page和rows的值才发生了变化,才会加载出下一页,显然不符合操作习惯。
那么有没有更合适解决方式呢,有的。将查询操作日志的js代码改成如下即可解决:
/**
* 查询操作日志
*/
function queryOperLog(){
$("#operLogList").datagrid({url:getUrl()+"/queryOperLog.do?"+$("#queryCondition").serialize()});
}
这样,是直接调用的插件的datagrid来实现异步加载。参数传递方面,它除了包含有$("#queryCondition").serialize(),还会自动带上分页栏中的page和rows,在datagrid内部再调用jquery中的post方法,将所有参数都传递过去。因此,调用控制器中queryOperLog方法就会成功,拿到结果集后就会渲染分页表格及其分页栏。
总结:用jQuery EasyUI插件实现分页,还是用datagrid更好,它会自动包含分页栏上的内容参数,传递到指定的url路径后台。当然,如果不通过点击“查询”按钮这种方式加载,而是进页面就分页加载的话,将异步加载的url路径以键值对的形式,放到视图中的data-options里面更好,这里就不列代码了,参照最上面的视图代码。