jquery.dataTables的探索之路-服務端分頁配置

最近閒來無事想研究下數據表格,由於以前接觸過layui和bootstrap的數據表格,本着能學多少學多少的學習態度,學習下dataTables的服務端分頁配置。特與同窗們一塊分享下從中遇到的問題和解決方式。javascript

 

與bootstrap的數據表略有不一樣,在引入相關js後除了必要的DOM節點(<table id="table" class="table table-responsive table-hover"></table>)外咱們還須要表頭部分,具體就是bootstrap的整張表格均可以經過js渲染,而dataTables的表頭部分須要咱們本身在頁面添加,就像下面這樣:java

<table id="table" class="table table-responsive table-hover">
   <thead>
       <tr>
          <th>ID</th>
          <th>文件名稱</th>
          <th>文件類型</th>
          <th>邏輯地址</th>
          <th>物理地址</th>
          <th>更新人</th>
          <th>更新時間</th>
       </tr>
   </thead>
</table>
                                        

 

我覺得dataTable的服務端分頁會像bootstrap同樣,給他一串url,剩下的交給他,因而我寫了以下代碼進行表格的初始化工做:jquery

<script type="text/javascript" src="static/assets/js/jquery-2.1.0.min.js"></script>
<script type="text/javascript" src="static/assets/libs/datatablejs/jquery.dataTables.min.js"></script>
<script type="text/javascript">
    initTable();

    function initTable() {
        var language = {"sProcessing": "處理中...", "sLengthMenu": "顯示 _MENU_ 項結果", "sZeroRecords": "沒有匹配結果", "sInfo": "當前第 _START_ 至 _END_ 條記錄,共 _TOTAL_ 條", "sInfoEmpty": "顯示第 0 至 0 項結果,共 0 項", "sInfoFiltered": "(共 _MAX_ 頁)", "sInfoPostFix": "", "sSearch": "搜索:", "sUrl": "", "sEmptyTable": "表中數據爲空", "sLoadingRecords": "載入中...", "sInfoThousands": ",", "oPaginate": {"sFirst": "首頁", "sPrevious": "上頁", "sNext": "下頁", "sLast": "末頁"}};
        $('#table').DataTable({
            'processing': true,
            'pageLength': 5, // 每頁顯示條數
            'ajax': '/admin/file/list', //異步請求地址
            'lengthChange': false,
            'searching': false,
            'info': true,
            'autoWidth': false, //自動列寬
            language: language, //國際化
            columns: [{
                data: "id" //綁定後臺數據列屬相
            }, {
                data: "filename"
            }, {
                data: 'filetype',
                defaultContent: "" //默認值
            }, {
                data: 'logicadress',
                defaultContent: ""
            }, {
                data: 'physicsadress',
                defaultContent: ""
            }, {
                data: 'modifyUser',
                defaultContent: "-"
            }, {
                data: 'modifyTime',
                defaultContent: ""
            }],
            columnDefs: [{ //自定義首列複選框
                targets: [0], //第幾列:默認從0開始
                orderable: false, // 是否支持排序
                render: function (id, type, row, meta) {
                    return '<input type="checkbox" name="ids" value=' + id + '><label for="input-' + id + '"></label>';
                }
            }]
        })
    }
</script>

刷新頁面結果以下:ajax












咦!!個人數據哪去啦?難道是請求除了問題?

查看控制檯,發現請求沒問題後臺數據也正常接收。json

對了,服務端返回數據的格式有問題!!後臺數據返回的是自定義JSON,不符合dataTables的默認值規範!!bootstrap

{"code":"200",
"msg":null,
"data":{
      "count":7,
      "totalPage":2,
      "pageSize":5,
      "currentPage":1,
      "list":[
            {"createUser":null,"createTime":"2019-05-28T14:24:56.000+0000","modifyUser":10000001,"modifyTime":"2019-05-09T14:24:59.000+0000","id":7,"filename":"女王大人","filetype":3,"logicadress":"www","physicsadress":"E:/test.txt","sort":"99"},
            {"createUser":null,"createTime":"2019-05-28T14:24:54.000+0000","modifyUser":10000001,"modifyTime":"2019-05-08T14:25:02.000+0000","id":6,"filename":"你的皇帝","filetype":2,"logicadress":"www","physicsadress":"E:/test.txt","sort":"99"},
            ...
          ],
      "sort":null,
      "order":null
     }
}

我在服務端封裝了返回的數據,致使dataTables不知道從哪下手!數組

在找到問題所在後,結合百老師的各類博客找到了解決的辦法:改造‘ajax’屬性app

$('#table').DataTable({
            ...
            'ajax': {
                url: '/admin/file/list',
                dataSrc: function (json) {
                    return json.data.list; //指定返回數據列的位置,該數據列爲數組形式
                }
            },
            ...
 })

經過指定數據列的位置,能夠實現對後臺自定義數據的渲染(一般狀況下會保證返回數據的統一格式):異步

再次刷新頁面數據能正常顯示了ide

嗯,很滿意。。但新的問題又出現了:分頁出毛病了,再查看控制檯發現我一共有7條記錄,按理說應該是2頁7條

經過百老師的大量博客,發現了問題所在:未開啓服務端分頁!!

繼續改造以下:

$('#table').DataTable({
            ...
            'serverSide': true,     // 開啓服務端分頁
            ... 
 )}

再次刷新頁面,意外發生了,很忽然:

出現了意想不到的事情:在開啓真正的服務端分頁後,個人數據又丟了!!

此次是後臺的錯誤,經過控制檯能夠發如今開啓服務端分頁後,dataTables在初始化時向後臺傳遞了不少參數:

能夠看到url後面拼接了一連串的字符串,致使後臺的SpringMVC在封裝參數時出現了問題:

    @GetMapping("file/list")
    public RestJson page(PageHelper pageHelper) {
        System.out.println(pageHelper);
        RestJson json = fileRecordService.getFileRecordByPage(pageHelper);
        return json;
    }

PageHelper是我自定義的分頁工具類具體代碼以下:

public class PageHelper<T> implements Serializable {

    private Integer count;//總記錄數
    private Integer totalPage;//總頁數
    private Integer pageSize;//每頁顯示的條數
    private Integer currentPage;//當前頁
    private List<T> list = new ArrayList<T>();//分頁以後的數據
    private String sort;//排序字段
    private String order;//升序或降序

    public Integer getCount() {
        return count;
    }

    public void setCount(Integer count) {
        this.count = count;
    }

    public Integer getTotalPage() {
        return totalPage;
    }

    public void setTotalPage(Integer totalPage) {
        this.totalPage = totalPage;
    }

    public Integer getPageSize() {
        return this.pageSize == null ? 5 : this.pageSize;
    }

    public void setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
    }

    public Integer getCurrentPage() {
        return this.currentPage == null ? 1 : this.currentPage;
    }

    public void setCurrentPage(Integer currentPage) {
        this.currentPage = currentPage;
    }

    public List<T> getList() {
        return list;
    }

    public void setList(List<T> list) {
        this.list = list;
    }

    public String getSort() {
        return this.sort == "" ? null : this.sort;
    }

    public void setSort(String sort) {
        this.sort = sort;
    }

    public String getOrder() {
        return this.order == "" ? null : this.order;
    }

    public void setOrder(String order) {
        this.order = order;
    }

    /**
     * 計算總頁數
     *
     * @return 總頁數
     */
    public int countPage() {
        int countPage = getCount() / getPageSize();
        return getCount() % getPageSize() == 0 ? countPage : countPage + 1;
    }

    /**
     * 從哪條開始取(當前記錄數)
     *
     * @return 當前記錄數
     */
    public int countOffSet() {
        return getPageSize() * (getCurrentPage() - 1);
    }

    /**
     * MYSQL
     * 取幾條
     *
     * @return 取幾條
     */
    public int countMySQLLength() {
        return getPageSize();
    }

    /**
     * ORACLE
     * 取幾條
     *
     * @return 取幾條
     */
    public int countOracleLength() {
        return getPageSize() * getCurrentPage();
    }

    @Override
    public String toString() {
        return "[ " +
                "count:" + count +
                " totalPage:" + totalPage +
                " pageSize:" + pageSize +
                " currentPage:" + currentPage +
                " sort:" + sort +
                " order:" + order +
                " ]";
    }
}

因爲SpringMVC封裝參數時出現了問題,因而我想能不能在dataTables初始化時自定義後臺傳遞的參數呢?

繼續改造‘ajax’屬性:

$('#table').DataTable({
           ...
            'ajax': {
                url: '/admin/file/list', // url請求
                data: function (data) { // 定義初始化參數 :data爲向後臺發送的參數obj
                    return $.extend( {},{}, { //自定義參數
                        "currentPage": data.start/data.length+1, //當前頁"pageSize": data.length, // 每頁顯示條數,data.length='pageLength'屬性的值 我設置的是5
                    } )
                },
                dataSrc: function (json) {
                    return json.data.list;
                }
            },
            ...
 )}    

再次刷新頁面,數據又回來了

等等,分頁是怎麼回事??不打緊,加上這兩句:

 $('#table').DataTable({
            ...
            'ajax': {
                ...
                dataSrc: function (json) {
                    json.recordsFiltered = json.data.count;  // 指定記錄數
                    json.recordsTotal = json.data.totalPage; // 指定頁數
                    return json.data.list;
                }
            },
            ...
 })

再次刷新頁面出現了預期的結果:

調試完畢,發現部分列不該該排序,查看‘columnDefs’屬性,發現ID列排序被禁用,但排序圖標初始化時依然存在。

添加以下屬性:

$('#table').DataTable({
            ...
            'order': [1,'asc'], //修改默認的排序列爲第2列、升序
            ...
 })

再次刷新頁面後正常顯示,能不能實現指定列排序呢?

修改代碼以下(爲了使代碼更簡潔我將‘columnDefs’屬性中的代碼轉移到‘columns’屬性中):

$('#table').DataTable({
            ...
            columns:[{  // 合併後的columns
                data: "id", // 綁定後臺數據列的屬性
                sortable: false, // 禁止排序
                render : function(id, type, row, meta) { // 將數據進行DOM轉換
                    return '<input type="checkbox" name="ids" value=' + id + '><label for="input-' + id + '"></label>';
                }
            },{
                data: "filename",
                render : function(id) {
                    return '<a href="javascript:;">'+id+'<a/>';
                }
            },{
                data: 'filetype',
                defaultContent : "",
                sortable: false,
            },{
                data: 'logicadress',
                defaultContent : "",
                sortable: false,
            },{
                data: 'physicsadress',
                defaultContent : "",
                sortable: false,
            },{
                data: 'modifyUser',
                defaultContent : "-",
                sortable: false,
            },{
                data: 'modifyTime',
                defaultContent : ""
            }],
       ... })

刷新頁面後效果以下:

點擊排序發現沒有反應。後臺的排序已經實現了,前臺只要發送相應的參數便可。

繼續修改代碼以下:

$('#table').DataTable({
            ...
            'ajax': {
                ...
                data: function (data) {
                    console.log(data);
                    return $.extend( {},{}, {
                        "currentPage": data.start/data.length+1,
                        "pageSize": data.length,
                        "order": data.order[0].dir, //升序或降序:隨鼠標點擊發生變化
                        "sort": data.order[0].column==1?"fileName":"modifyTime" //獲取排序列:下標從0開始,1表明第二列(由於只有兩列參與排序,因此簡單寫了)
                    } )
                },
                ...
            },
            ...
 })

刷新頁面,打開控制檯,咱們看下‘data’的結構:

{
  "draw": 1,
  "columns": [
    {
      "data": "id","name": "","searchable": true,"orderable": false,
      "search": {"value": "", "regex": false}
    },
    ...
  ],
  "order": [{"column": 1,"dir": "asc"}],
  "start": 0,
  "length": 5,
  "search": {"value": "","regex": false}
}

一個標準的json對象,如今回頭看看這兩行代碼是否是有種恍然大悟的感受:

"order": data.order[0].dir, 
"sort": data.order[0].column==1?"fileName":"modifyTime"

後臺的分頁和排序代碼無須贅述,本文主要是分享在使用dataTables時如何自定義先後臺參數問題,其實使用起來和bootstrap的數據表格有不少類似的地方,感受仍是後者更簡單一些。鹹魚水平,不足之處歡迎指正!

相關文章
相關標籤/搜索