本文是jquery<--json-->spring(3.0)系列的第三篇。html
原文地址:http://blog.csdn.net/hy840429/article/details/5626878java
jquery與yui相比,感受寫法很簡潔,但也有個問題是配套的jquery ui中的頁面控件
不是很全,不少要藉助plugin,而這些plugin參差不齊,選用時要本身好好挑一挑。
列表是一個經常使用的頁面控件,我選了半天發現DataTables這款用的人比較多,就試了
試服務器端翻頁功能,現總結以下。
DataTables的主頁是http://www.datatables.net/
先上個這個demo的截圖,設想的操做是輸入客戶名稱,按檢索後進行模糊檢索進行分
頁顯示,每頁顯示8條記錄。
![點擊查看原始大小圖片](http://static.javashuo.com/static/loading.gif)
1 頁面部分
使用DataTables時,html須要以下書寫,其中tfoot部分是表表格的下部標題,能夠不
要。jquery
- <table class="display" id="customerInfo">
- <thead>
- <tr>
- <th>ID</th>
- 略
- <th>身高</th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <td colspan="8"></td>
- </tr>
- </tbody>
- <tfoot>
- <tr>
- <th>ID</th>
- 略
- <th>身高</th>
- </tr>
- </tfoot>
- </table>
js部分這樣寫:ajax
- $('#customerInfo').dataTable();
對於從服務器端取數據,還要指定幾個參數:
bServerSide:true
sAjaxSource:獲取數據的url
這樣,在DataTables須要數據時會調用jquery的getJSON獲取數據,其中url就是sAjaxSource,
同時傳遞一堆自定義的參數,包括須要顯示的起始記錄數,須要顯示的記錄數,列數,排序
列等等,具體能夠參看這裏http://www.datatables.net/usage/server-side。其中一個比較
特殊的是sEcho,這個參數須要之後原封不動地返回給頁面。
因爲默認是以$.getJSON發送請求,因此http命令是GET,參數是以url參數的方式傳遞的,我
但願以POST命令,以json方式發送請求,並且要加上客戶名稱這個參數,因此這裏須要作些修
改。
DataTables經過fnServerData提供了這樣一個接口,fnServerData是與服務器端交換數據時被
調用的函數,默認實現是如上所說的經過getJSON發送請求,而後接收特定格式的json數據(這
個在服務器端處理部分再說)。fnServerData會接到3個參數:
sSource: 接收數據的url,就是sAjaxSource中指定的地址
aoData:DataTables定義的參數,是一個數組,其中每一個元素是一個name-value對,我須要
把客戶名稱這個參數加進去
fnCallback:服務器返回數據後的處理函數,我須要按DataTables指望的格式傳入返回數據
最後自定義的fnServerData以下所示:spring
- function retrieveData( sSource, aoData, fnCallback ) {
- //將客戶名稱加入參數數組
- aoData.push( { "name": "customerName", "value": $("#customerName").val() } );
-
- $.ajax( {
- "type": "POST",
- "contentType": "application/json",
- "url": sSource,
- "dataType": "json",
- "data": JSON.stringify(aoData), //以json格式傳遞
- "success": function(resp) {
- fnCallback(resp.returnObject); //服務器端返回的對象的returnObject部分是要求的格式
- }
- });
- }
頁面的初始化及查詢按鈕的處理函數以下所示:json
- var oTable = null;
-
- $(function() {
- $("#customerInfo").hide();
- } );
-
- //「檢索」按鈕的處理函數
- function search() {
- if (oTable == null) { //僅第一次檢索時初始化Datatable
- $("#customerInfo").show();
- oTable = $('#customerInfo').dataTable( {
- "bAutoWidth": false, //不自動計算列寬度
- "aoColumns": [ //設定各列寬度
- {"sWidth": "15px"},
- {"sWidth": "80px"},
- {"sWidth": "160px"},
- {"sWidth": "110px"},
- {"sWidth": "120px"},
- {"sWidth": "140px"},
- {"sWidth": "140px"},
- {"sWidth": "*"}
- ],
- "bProcessing": true, //加載數據時顯示正在加載信息
- "bServerSide": true, //指定從服務器端獲取數據
- "bFilter": false, //不使用過濾功能
- "bLengthChange": false, //用戶不可改變每頁顯示數量
- "iDisplayLength": 8, //每頁顯示8條數據
- "sAjaxSource": "customerInfo/search.do",//獲取數據的url
- "fnServerData": retrieveData, //獲取數據的處理函數
- "sPaginationType": "full_numbers", //翻頁界面類型
- "oLanguage": { //漢化
- "sLengthMenu": "每頁顯示 _MENU_ 條記錄",
- "sZeroRecords": "沒有檢索到數據",
- "sInfo": "當前數據爲從第 _START_ 到第 _END_ 條數據;總共有 _TOTAL_ 條記錄",
- "sInfoEmtpy": "沒有數據",
- "sProcessing": "正在加載數據...",
- "oPaginate": {
- "sFirst": "首頁",
- "sPrevious": "前頁",
- "sNext": "後頁",
- "sLast": "尾頁"
- }
- }
- });
- }
-
- //刷新Datatable,會自動激發retrieveData
- oTable.fnDraw();
- }
2 服務器端
頁面請求的參數是一個數組,其中每一個元素是一個name-value對,我以下定義數組
- public class JSONParam {
- private String name;
- private String value;
-
- //略
- }
對應的處理函數以下定義:服務器
- @RequestMapping(value = "/search", method = RequestMethod.POST)
- @ResponseBody
- public JSONResponse search(@RequestBody JSONParam[] params){
- //略
- }
在這個函數裏大體的處理是先取出所需的參數,而後檢索數據,最後將DataTables指望的
格式的數據放入返回對象JSONResponse的returnObject部分。
DataTables指望的數據格式以下:
{
"sEcho": 頁面發來的參數,原樣返回,
"iTotalRecords": 過濾前總記錄數,
"iTotalDisplayRecords": 過濾後總記錄數,我沒有使用過濾,不太清楚和iTotalRecords的區別,
"aaData": 包含數據的2維數組
}
對應的java定義以下:app
- public class DataTableReturnObject {
- private long iTotalRecords;
- private long iTotalDisplayRecords;
- private String sEcho;
- private String[][] aaData;
-
- public DataTableReturnObject(long totalRecords, long totalDisplayRecords, String echo, String[][] d) {
- //略
- }
-
- //略
- }
完整的服務器端處理函數以下:ide
- @RequestMapping(value = "/search", method = RequestMethod.POST)
- @ResponseBody
- public JSONResponse search(@RequestBody JSONParam[] params) throws IllegalAccessException, InvocationTargetException
- //convertToMap定義於父類,將參數數組中的全部元素加入一個HashMap
- HashMap<String, String> paramMap = convertToMap(params);
- String sEcho = paramMap.get("sEcho");
- String customerName = paramMap.get("customerName");
- int start = Integer.parseInt(paramMap.get("iDisplayStart"));
- int length = Integer.parseInt(paramMap.get("iDisplayLength"));
-
- //customerService.search返回的第一個元素是知足查詢條件的記錄總數,後面的是
- //頁面當前頁須要顯示的記錄數據
- List<Object> customerList = customerService.search(customerName, start, length);
- Long count = (Long)customerList.get(0);
-
- //將查詢結果轉換爲一個二維數組
- int record = customerList.size() - 1;
- String[][] data = new String[record][];
- for(int i=0; i<record; i++) {
- Customer customer = (Customer)customerList.get(i+1);
- JSONCustomer jsonCustomer = new JSONCustomer();
- BeanUtils.copyProperties(jsonCustomer, customer);
- data[i] = jsonCustomer.toArray();
- }
-
- return successed(new DataTableReturnObject(count.longValue(), count.longValue(), sEcho, data));
- }
數據返回到頁面後,如上所述,取出response中的returnObject交給DataTables的函數進行處理 就能夠了