经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » jQuery » 查看文章
jquery.dataTables的摸索之路-服务端分页配置
来源:cnblogs  作者:王文竹  时间:2019/6/13 8:55:47  对本文有异议

最近闲来无事想研究下数据表格,因为之前接触过layui和bootstrap的数据表格,本着能学多少学多少的学习态度,学习下dataTables的服务端分页配置。特与同学们一块分享下从中遇到的问题和解决方式。

 

与bootstrap的数据表略有不同,在引入相关js后除了必要的DOM节点(<table id="table" class="table table-responsive table-hover"></table>)外我们还需要表头部分,具体就是bootstrap的整张表格都可以通过js渲染,而dataTables的表头部分需要我们自己在页面添加,就像下面这样:

  1. <table id="table" class="table table-responsive table-hover">
  2. <thead>
  3. <tr>
  4. <th>ID</th>
  5. <th>文件名称</th>
  6. <th>文件类型</th>
  7. <th>逻辑地址</th>
  8. <th>物理地址</th>
  9. <th>更新人</th>
  10. <th>更新时间</th>
  11. </tr>
  12. </thead>
  13. </table>

 

我以为dataTable的服务端分页会像bootstrap一样,给他一串url,剩下的交给他,于是我写了如下代码进行表格的初始化工作:

  1. <script type="text/javascript" src="static/assets/js/jquery-2.1.0.min.js"></script>
  2. <script type="text/javascript" src="static/assets/libs/datatablejs/jquery.dataTables.min.js"></script>
  1. <script type="text/javascript">
  2. initTable();
  3. function initTable() {
  4. 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": "末页"}};
  5. $('#table').DataTable({
  6. 'processing': true,
  7. 'pageLength': 5, // 每页显示条数
  8. 'ajax': '/admin/file/list', //异步请求地址
  9. 'lengthChange': false,
  10. 'searching': false,
  11. 'info': true,
  12. 'autoWidth': false, //自动列宽
  13. language: language, //国际化
  14. columns: [{
  15. data: "id" //绑定后台数据列属相
  16. }, {
  17. data: "filename"
  18. }, {
  19. data: 'filetype',
  20. defaultContent: "" //默认值
  21. }, {
  22. data: 'logicadress',
  23. defaultContent: ""
  24. }, {
  25. data: 'physicsadress',
  26. defaultContent: ""
  27. }, {
  28. data: 'modifyUser',
  29. defaultContent: "-"
  30. }, {
  31. data: 'modifyTime',
  32. defaultContent: ""
  33. }],
  34. columnDefs: [{ //自定义首列复选框
  35. targets: [0], //第几列:默认从0开始
  36. orderable: false, // 是否支持排序
  37. render: function (id, type, row, meta) {
  38. return '<input type="checkbox" name="ids" value=' + id + '><label for="input-' + id + '"></label>';
  39. }
  40. }]
  41. })
  42. }
  43. </script>

刷新页面结果如下:












  1. 咦!!我的数据哪去啦?难道是请求除了问题?

查看控制台,发现请求没问题后台数据也正常接收。

对了,服务端返回数据的格式有问题!!后台数据返回的是自定义JSON,不符合dataTables的默认值规范!!

  1. {"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"},
                {"createUser":null,"createTime":"2019-05-28T14:24:51.000+0000","modifyUser":10000001,"modifyTime":"2019-05-07T14:25:04.000+0000","id":5,"filename":"阿里斯嘉","filetype":0,"logicadress":"www","physicsadress":"E:/test.txt","sort":"99"},
                {"createUser":null,"createTime":"2019-05-28T14:24:49.000+0000","modifyUser":10000001,"modifyTime":"2019-05-06T14:25:07.000+0000","id":4,"filename":"马大哈","filetype":1,"logicadress":"www","physicsadress":"E:/test.txt","sort":"99"},
                {"createUser":null,"createTime":"2019-05-28T14:24:46.000+0000","modifyUser":10000001,"modifyTime":"2019-05-05T14:25:09.000+0000","id":3,"filename":"土豆司","filetype":1,"logicadress":"www","physicsadress":"E:/test.txt","sort":"99"}
              ],
          "sort":null,
          "order":null
         }
    }

我在服务端封装了返回的数据,导致dataTables不知道从哪下手!

在找到问题所在后,结合百老师的各种博客找到了解决的办法:改造‘ajax’属性

  1. $('#table').DataTable({
  2. ...
  3. 'ajax': {
  4. url: '/admin/file/list',
  5. dataSrc: function (json) {
  6. return json.data.list; //指定返回数据列的位置,该数据列为数组形式
  7. }
  8. },
  9. ...
  10. })

通过指定数据列的位置,可以实现对后台自定义数据的渲染(通常情况下会保证返回数据的统一格式):

再次刷新页面数据能正常显示了

嗯,很满意。。但新的问题又出现了:分页出毛病了,再查看控制台发现我一共有7条记录,按理说应该是2页7条

通过百老师的大量博客,发现了问题所在:未开启服务端分页!!

继续改造如下:

  1. $('#table').DataTable({
  2. ...
  3. 'serverSide': true, // 开启服务端分页
  4. ...
  5. )}

再次刷新页面,意外发生了,很突然:

出现了意想不到的事情:在开启真正的服务端分页后,我的数据又丢了!!

这次是后台的错误,通过控制台可以发现在开启服务端分页后,dataTables在初始化时向后台传递了很多参数:

可以看到url后面拼接了一连串的字符串,导致后台的SpringMVC在封装参数时出现了问题:

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

PageHelper是我自定义的分页工具类具体代码如下:

  1. public class PageHelper<T> implements Serializable {
  2. private Integer count;//总记录数
  3. private Integer totalPage;//总页数
  4. private Integer pageSize;//每页显示的条数
  5. private Integer currentPage;//当前页
  6. private List<T> list = new ArrayList<T>();//分页之后的数据
  7. private String sort;//排序字段
  8. private String order;//升序或降序
  9.  
  10. public Integer getCount() {
  11. return count;
  12. }
  13. public void setCount(Integer count) {
  14. this.count = count;
  15. }
  16. public Integer getTotalPage() {
  17. return totalPage;
  18. }
  19. public void setTotalPage(Integer totalPage) {
  20. this.totalPage = totalPage;
  21. }
  22. public Integer getPageSize() {
  23. return this.pageSize == null ? 5 : this.pageSize;
  24. }
  25. public void setPageSize(Integer pageSize) {
  26. this.pageSize = pageSize;
  27. }
  28. public Integer getCurrentPage() {
  29. return this.currentPage == null ? 1 : this.currentPage;
  30. }
  31. public void setCurrentPage(Integer currentPage) {
  32. this.currentPage = currentPage;
  33. }
  34. public List<T> getList() {
  35. return list;
  36. }
  37. public void setList(List<T> list) {
  38. this.list = list;
  39. }
  40. public String getSort() {
  41. return this.sort == "" ? null : this.sort;
  42. }
  43. public void setSort(String sort) {
  44. this.sort = sort;
  45. }
  46. public String getOrder() {
  47. return this.order == "" ? null : this.order;
  48. }
  49. public void setOrder(String order) {
  50. this.order = order;
  51. }
  52. /**
  53. * 计算总页数
  54. *
  55. * @return 总页数
  56. */
  57. public int countPage() {
  58. int countPage = getCount() / getPageSize();
  59. return getCount() % getPageSize() == 0 ? countPage : countPage + 1;
  60. }
  61. /**
  62. * 从哪条开始取(当前记录数)
  63. *
  64. * @return 当前记录数
  65. */
  66. public int countOffSet() {
  67. return getPageSize() * (getCurrentPage() - 1);
  68. }
  69. /**
  70. * MYSQL
  71. * 取几条
  72. *
  73. * @return 取几条
  74. */
  75. public int countMySQLLength() {
  76. return getPageSize();
  77. }
  78. /**
  79. * ORACLE
  80. * 取几条
  81. *
  82. * @return 取几条
  83. */
  84. public int countOracleLength() {
  85. return getPageSize() * getCurrentPage();
  86. }
  87. @Override
  88. public String toString() {
  89. return "[ " +
  90. "count:" + count +
  91. " totalPage:" + totalPage +
  92. " pageSize:" + pageSize +
  93. " currentPage:" + currentPage +
  94. " sort:" + sort +
  95. " order:" + order +
  96. " ]";
  97. }
  98. }

由于SpringMVC封装参数时出现了问题,于是我想能不能在dataTables初始化时自定义后台传递的参数呢?

继续改造‘ajax’属性:

  1. $('#table').DataTable({
  2. ...
  3. 'ajax': {
  4. url: '/admin/file/list', // url请求
  5. data: function (data) { // 定义初始化参数 :data为向后台发送的参数obj
  6. return $.extend( {},{}, { //自定义参数
  7. "currentPage": data.start/data.length+1, //当前页"pageSize": data.length, // 每页显示条数,data.length='pageLength'属性的值 我设置的是5
  8. } )
  9. },
  10. dataSrc: function (json) {
  11. return json.data.list;
  12. }
  13. },
  14. ...
  15. )}

再次刷新页面,数据又回来了

等等,分页是怎么回事??不打紧,加上这两句:

  1. $('#table').DataTable({
  2. ...
  3. 'ajax': {
  4. ...
  5. dataSrc: function (json) {
  6. json.recordsFiltered = json.data.count; // 指定记录数
  7. json.recordsTotal = json.data.totalPage; // 指定页数
  8. return json.data.list;
  9. }
  10. },
  11. ...
  12. })

再次刷新页面出现了预期的结果:

调试完毕,发现部分列不应该排序,查看‘columnDefs’属性,发现ID列排序被禁用,但排序图标初始化时依然存在。

添加如下属性:

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

再次刷新页面后正常显示,能不能实现指定列排序呢?

修改代码如下(为了使代码更简洁我将‘columnDefs’属性中的代码转移到‘columns’属性中):

  1. $('#table').DataTable({
  2. ...
  3. columns:[{ // 合并后的columns
  4. data: "id", // 绑定后台数据列的属性
  5. sortable: false, // 禁止排序
  6. render : function(id, type, row, meta) { // 将数据进行DOM转换
  7. return '<input type="checkbox" name="ids" value=' + id + '><label for="input-' + id + '"></label>';
  8. }
  9. },{
  10. data: "filename",
  11. render : function(id) {
  12. return '<a href="javascript:;">'+id+'<a/>';
  13. }
  14. },{
  15. data: 'filetype',
  16. defaultContent : "",
  17. sortable: false,
  18. },{
  19. data: 'logicadress',
  20. defaultContent : "",
  21. sortable: false,
  22. },{
  23. data: 'physicsadress',
  24. defaultContent : "",
  25. sortable: false,
  26. },{
  27. data: 'modifyUser',
  28. defaultContent : "-",
  29. sortable: false,
  30. },{
  31. data: 'modifyTime',
  32. defaultContent : ""
  33. }],
           ...
  34. })

刷新页面后效果如下:

点击排序发现没有反应。后台的排序已经实现了,前台只要发送相应的参数即可。

继续修改代码如下:

  1. $('#table').DataTable({
  2. ...
  3. 'ajax': {
  4. ...
  5. data: function (data) {
  6. console.log(data);
  7. return $.extend( {},{}, {
  8. "currentPage": data.start/data.length+1,
  9. "pageSize": data.length,
  10. "order": data.order[0].dir, //升序或降序:随鼠标点击发生变化
  11. "sort": data.order[0].column==1?"fileName":"modifyTime" //获取排序列:下标从0开始,1代表第二列(因为只有两列参与排序,所以简单写了)
  12. } )
  13. },
  14. ...
  15. },
  16. ...
  17. })

刷新页面,打开控制台,我们看下‘data’的结构:

  1. {
  2. "draw": 1,
  3. "columns": [
  4. {
  5. "data": "id","name": "","searchable": true,"orderable": false,
  6. "search": {"value": "", "regex": false}
  7. },
  8. ...
  9. ],
  10. "order": [{"column": 1,"dir": "asc"}],
  11. "start": 0,
  12. "length": 5,
  13. "search": {"value": "","regex": false}
  14. }

一个标准的json对象,现在回头看看这两行代码是不是有种恍然大悟的感觉:

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

后台的分页和排序代码无须赘述,本文主要是分享在使用dataTables时如何自定义前后台参数问题,其实使用起来和bootstrap的数据表格有很多相似的地方,感觉还是后者更简单一些。咸鱼水平,不足之处欢迎指正!

原文链接:http://www.cnblogs.com/wangwz2019/p/11011264.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号