zoukankan      html  css  js  c++  java
  • DataTables API及服务端处理模式介绍和后端分页案例

    一.DataTables概述

    Datatables是一款jquery表格插件.是一个高度灵活的工具,可以将任何HTML表格添加高级的交互功能.支持

    • 分页,即时搜索和排序
    • 支持数据源: DOM, JavaScript, Ajax 和服务器处理
    • 支持不同的主题: DataTables, jqueryUI, Bootstrap, Foundation
    • 支持国际化和多样的option选项

    官方网址:

    1.处理数据的三个核心概念

    1.1 处理模式(processing modes)

    DataTables 中有两种不同的方式处理数据(排序、搜索、分页等):

    • 客户端处理(Client)—— 所有的数据集预先加载(一次获取所有数据),数据处理都是在浏览器中完成的【逻辑分页】, 适用于数据量小。
    • 服务器端处理(ServerSide)—— 数据处理是在服务器上执行(页面只处理当前页的数据)【物理分页】,适用于数据量大。

    注意:两种处理模式不能同时使用,但是可以动态更改从一个模式到另一个。

    1.2 数据源类型(data source types)

    DataTables 使用的数据源必须是一个数组,数组里的每一项将显示在你定义的行上面,DataTables 可以使用三种基本的 JavaScript 数据类型来作为数据源:

    • 数组(Array [])
    • 对象(object {}) -- 常使用
    • 实例(new myclass())
    1.3 数据源(data sources)

    DataTables 支持三种数据源显示:

    • DOM
    • Javascript
    • Ajax -- 常使用

    2.安装datatables插件

    将media文件下的内容全部放到工程下,html页面引入即可使用:

    <!-- jQuery -->
    <script type="text/javascript" src="media/js/jquery.js"></script>
    
    <!-- DataTables -->
    <link rel="stylesheet" type="text/css" href="media/css/jquery.dataTables.css">
    <script type="text/javascript" src="media/js/jquery.dataTables.js"></script>
    

    继续在html页面引入datatables的bootstrap样式:

    <!-- CSS -->
    <link rel="stylesheet" type="text/css" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css">
    <link rel="stylesheet" type="text/css" href="media/css/dataTables.bootstrap4.css">
    <!-- jQuery -->
    <script type="text/javascript" src="media/js/jquery.js"></script>
    <!-- dataTables.js -->
    <script type="text/javascript" src="media/js/jquery.dataTables.js"></script>
    <script type="text/javascript" src="media/js/dataTables.bootstrap4.js"></script>
    

    3.Option API

    文档: http://datatables.club/reference/option/

    国际化zh_CN.json文件:

    {
        "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": "末页",
            "sJump": "跳转"
         },
         "oAria": {
             "sSortAscending": ": 以升序排列此列",
             "sSortDescending": ": 以降序排列此列"
         }
    }
    

    常用Option API介绍:

    $(function() {
      $("#table_id").DataTable({
        language: {	//异步加载翻译,支持国际化
          url:"dist/zh_CN.json"	//在static资源文件夹下
        },
        info: true,	//显示页脚信息
        lengthChange: true, //显示更换记录数下拉选
        aLengthMenu : [6, 16, 32, 64], //更改显示记录数选项
        iDisplayLength : 6, //默认显示的记录数
        
        searching: false, //禁用原生搜索
        filter: false, //去掉搜索框方法,过滤功能
        
        ordering: true,	//开启排序
        orderMulti: false, //禁用多列排序
        order: [[ 3, "desc" ]], //取消默认排序查询,否则复选框一列会出现小箭头
        buttons:  ['copy', 'excel', 'pdf']	//开启下载数据为各种格式按钮
        
        renderer: "bootstrap", //渲染样式:Bootstrap和jquery-ui
        stripeClasses: ["odd", "even"], //为奇偶行加上样式,兼容不支持CSS伪类的场合
        
        paging: true,	//开启分页
        pageLength: 3, //每页显示3条数据,pagesize
        pagingType: "simple_numbers", //分页样式:simple,simple_numbers,full,full_numbers
        
        scrollX: true,  //启动水平滚动
        sScrollX : 820, //指定DataTables的宽    
        scrollY: true,	//启动垂直滚动
        sScrollY : 560, //指定DataTables的高
        autoWidth: false, //禁用自动调整列宽
        
        processing: true, //显示加载提示,自行处理
        serverSide: true, //开启服务器端分页
        ajax: {	//使用ajax异步请求的方式加载数据(包括处理分页,排序,搜索)
            url: '/data-source',	//请求的URL地址
            type: 'GET'	//使用GET请求的方式
        },
    	columns: [	// 指定数据源,与服务器端响应的数据一一对应,使用对象数组
          { data: 'buildName',  "60px", defaultContent: "<i></i>"},
          { data: 'totalCases',  "120px", defaultContent: "<i></i>"},
          { data: 'failCases',  "120px", defaultContent: "<i></i>"},
          { data: 'passRate',  "120px", defaultContent: "<i></i>"},
          { data: 'detail',  "120px", defaultContent: "<i></i>"},
          { data: 'loginfo',  "120px", defaultContent: "<i></i>"}   
        ],
        columnDefs: [{
          "targets": 'nosort', //指定class为nosort的列
          "orderable": false, //包含上样式名‘nosort'的禁止排序
          "data": 'loginfo',	//指定引用loginfo的数据源
          render: function (data, type, row) {
            //可对数据进行处理,再显示
            var html = '<a  href="'+data+'" target="_blank" class="btn btn-success btn-sm">logInfo</a>';
            return html;
          }
        }],
        
      });
    });
    

    二.服务器处理模式

    表格数据量如果很大,超过5000行的话,建议使用后台分页功能。关于这个功能的一些参数:

    • 开关:表格初始化时的选项,字段为serverSide,true表示使用后台分页功能

    • datatables发送的数据:使用ajax自定义的方法时, data字段增加了下面三个属性, start和length其实对应的是sql语句limit之后的两个参数

      描述 字段
      draw 绘制计数器。这个是用来确保Ajax从服务器返回的是对应的(Ajax是异步的,因此返回的顺序是不确定的)。 要求在服务器接收到此参数后再返回
      start 第一条数据的起始位置,比如0代表第一条数据
      length 告诉服务器每页显示的条数,这个数字会等于返回的 data集合的记录数,可能会大于因为服务器可能没有那么多数据。这个也可能是-1,代表需要返回全部数据(尽管这个和服务器处理的理念有点违背)
      其它 还有一些字段指定了哪些列需要排序 和 搜索条件等
    • datatables接受的数据:要求4个参数,分别是:

      • draw请求时的标记字段 ,直接返回
      • recordsTotal,表格总长度,总记录数
      • recordsFiltered,根据返送的过滤条件 过滤后的数据数,通常可以直接和recordsFiltered相同
      • data,表中中需要显示的数据。这是一个对象数组,也可以只是数组,区别在于 纯数组前台就不需要用 columns绑定数据,会自动按照顺序去显示 ,而对象数组则需要使用 columns绑定数据才能正常显示。

    需要注意的是,对于后台返回空时,需要将表格长度置为0,否则表格下面的分页按钮不会变化,延续上次结果

    1.html页面中table

    <!-- 冒烟 -->
    <div class="row" id="pre_alpha_smoke">
      <div class="col-md-12">
        <h4 class="text-center bg-secondary" style="margin: 24px 0px;">冒烟</h4>
    
        <table id="pre_alpha_smoke_table" class="table table-bordered table-striped" style=" 100%;">
          <thead align='center' valign="middle">
            <tr>
              <th>版本名称</th>
              <th>总用例数</th>
              <th>失败用例数</th>
              <th>脚本通过率</th>
              <th>测试结果</th>
              <th>日志信息</th>
            </tr>
          </thead>
          <tbody align='center' valign="middle">
            <tr>
              <td>1902v52</td>
              <td>188</td>
              <td>16</td>
              <td><span class="badge bg-success">100%</span></td>
              <td>ok</td>
              <td><a href="http://10.150.99.10:8080/jenkins/job/SMOKE_TEST_5/926/consoleText" target="_blank">logLink</a></td>
            </tr>
          </tbody>
        </table>
      </div>
      <!-- /.col -->
    </div>
    <!-- /.row -->
    

    2.table的js文件

    $(function () {
        var catalog = 'smoke';
        var project = 'X653C-H6114GH-PGo';
        var starttime = '2019-08-30 00:00:01';
        var endtime = '2020-01-16 23:59:59';
    
        //封装相应的请求参数,这里获取页大小和当前页码
        // var param = {};
        // param.pagesize = data.length;//页面显示记录条数,在页面显示每页显示多少项的时候,页大小
        // param.start = data.start;//开始的记录序号
      	// param.draw = data.draw;//标记字段
        // param.currentPage = (data.start) / data.length + 1;//当前页码
    
        $("#pre_alpha_smoke_table").DataTable({
            // 语言国际化
            language: {
                url:"dist/zh_CN.json"
            },
            info : true,
            paging: true,
            aLengthMenu : [6, 16, 32, 64], //更改显示记录数选项
            iDisplayLength : 6, //默认显示的记录数
            // pageLength: 3, //每页显示3条数据
            processing: false,   //显示加载提示,自行处理
            searching: true,    //显示原生搜索
            stripeClasses: ["odd", "even"], //为奇偶行加上样式,兼容不支持CSS伪类的场合
            pagingType: "full_numbers", //分页样式:simple,simple_numbers,full,full_numbers
            serverSide: true,   //开启服务器模式
            //数据来源(包括处理分页,排序,过滤) ,即url,action,接口,等等
            ajax: function (data, callback, setting) {
                var flag = data.draw;//标记字段
                var pagesize = data.length;//当前页大小
                var currentPage = (data.start) / data.length + 1;//当前页码
                $.ajax({
                    type: "GET",
                    url: "http://localhost:8081/api/testresult/"+catalog+"/"+project+"/"+starttime+"/"+endtime+"/"+currentPage+"/"+pagesize,
                    cache: false, //禁用缓存
                    data: {}, //传入组装的参数
                    dataType: "json",
                    success: function (result) {
                        console.log(result);
                        var returnData = {};
                        // returnData.draw = result.pageInfo.draw;//这里直接自行返回了draw计数器,应该由后台返回,没什么卵用!
                        returnData.recordsTotal = result.pageInfo.recordsTotal;//返回数据全部记录
                        returnData.recordsFiltered = result.pageInfo.recordsFiltered;//后台不实现过滤功能,每次查询均视作全部结果
                        returnData.data = result.pageInfo.data;//返回的数据列表
                        //此时的数据需确保正确无误,异常判断应在执行此回调前自行处理完毕
                        callback(returnData);
                    }
                });
            },
            //使用对象数组,一定要配置columns,告诉 DataTables 每列对应的属性
            //data 这里是固定不变的,name,position,salary,office 为你数据里对应的属性
            columns: [
                { data: 'buildName' },
                { data: 'totalCases' },
                { data: 'failCases' },
                { data: 'passRate' },
                { data: 'detail' },
                {
                    data: 'loginfo'
                    /*render: function (data, type, full) {
                        //可对数据进行处理,再显示
                        var html = '<a  href="'+data+'" target="_blank" class="btn btn-success btn-sm">logInfo</a>';
                        return html;
                    }*/
                }
            ],
            "columnDefs" : [{
                "targets" : 5,  //索引从0开始,将索引值所在的列重新定义
                "data" : 'loginfo',
                render: function (data, type, full) {
                    //可对数据进行处理,再显示
                    var html = '<a  href="'+data+'" target="_blank" class="btn btn-success btn-sm">logInfo</a>';
                    return html;
                }
            }],
            //列样式处理
            "fnRowCallback": function (nRow, aData, iDisplayIndex, iDisplayIndexFull) {
            },
            // 切换下一页更新复选框的状态为不选中:重绘的回调函数,更新状态
            "fnDrawCallback" : function() {
            },
        });
    
    })
    

    3.后端Controller类

    @RestController
    @RequestMapping("/api")
    public class SmokeResultController {
      
      private final Logger log =  LoggerFactory.getLogger(SmokeResultController.class);
    
      @Autowired
      private SmokeResultService smokeResultService;
      
      // 获采用datatables前端插件的服务器端处理模式  -- 后端分页(需要传入currentPage和pageSize)
      @GetMapping("/testresult/{catalog}/{project}/{starttime}/{endtime}/{currentPage}/{pagesize}")
      public ResponseEntity<TestResultResponse> getPhaseSmokeResult(@PathVariable("catalog")String catalog,@PathVariable("project")String project,@PathVariable("starttime")String starttime,@PathVariable("endtime")String endtime,
    @PathVariable("currentPage")Integer currentPage,@PathVariable("pagesize")Integer pagesize){
        log.debug("REST request to get {} phase smoke result from {} to {} ", project, starttime, endtime);
        TestResultResponse response = smokeResultService.getPhaseSmokeResult(catalog,project,starttime,endtime,currentPage,pagesize);
        return new ResponseEntity<>(response, HttpStatus.OK);
      }
      
    }
    

    serviceImpl类:

    @Service
    public class SmokeResultServiceImpl implements SmokeResultService{
      
      @Autowired
      private SmokeResultMapper smokeResultMapper;
      
      @Override
        public TestResultResponse getPhaseSmokeResult(String catalog, String project, String starttime, String endtime, Integer currentPage, Integer pagesize) {
            PageHelper.startPage(currentPage, pagesize);//pageHelper分页插件,只对后续一条语句起作用
            List<SmokeResult> smokeResultList = smokeResultMapper.getPhaseSmokeResult(project,starttime,endtime);
            PageInfo<SmokeResult> pageInfo = new PageInfo<>(smokeResultList);
            TestResultResponse response = new TestResultResponse();
            response.setCatalog(catalog).setProject(project).setStarttime(starttime).setEndtime(endtime).setPageInfo(pageInfo);
            return response;
        }
      
    }
    

    entity类:

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Accessors(chain = true)
    public class TestResultResponse {
    
    	private String project;
    	private String version;
    	private String starttime;
    	private String endtime;
    	private String pass;
    	private String fail;
    	private String total;
        private String catalog;
    	private PageInfo pageInfo;
    
    }
    

    4.PageInfo类

    public class PageInfo<T> {
    
        private Integer draw;//绘制计数器
        private Integer start;//每页第一条数据的起始位置
        private Integer length;//每页显示的条数
        private Long recordsTotal;//总记录数
        private Long recordsFiltered;//过滤后的数据数
        private List<T> data;//表中需要显示的数据
        
    }
    

    5.效果图

    在这里插入图片描述

    三.客服端处理模式

    当数据量比较小时,可以采用datatables自动分页,一次将数据全部获取,分页交给浏览器处理,逻辑分页.这里就不需要开启serverSide和使用自带的ajax请求了.

    $(function() {
        $("#pre_alpha_smoke_table").dataTable({	// 客户端模式这样初始化配置就可以
            language: {
              url:"dist/zh_CN.json"
            },
            "aLengthMenu" : [3, 16, 32, 64], //更改显示记录数选项
            "iDisplayLength" : 3, //默认显示的记录数
            "lengthChange": false,	//禁用更换记录数的下拉选
            "searching": false,	//禁用搜搜框
        });
      
      	var starttime = '2020-03-02 01:51:20';
        var endtime = '2020-03-02 12:51:20';
      
        ajax({
          type: 'get',
          dataType: 'json',
          url: 'http://localhost:8081/api/testresult/smoke/HIOS6.0-Q-MP-KB8-P70/all',
          data: {
            'starttime': starttime,
            'endtime': endtime
          },
          cache: false,
          async: true,
          success: function (data) {
            console.log(data);
            // 获取项目名称
            $("#projectname").html(data.project);
    
            // 获取pre-alpha的monkey上海数据
            var monkey_sh = data.detail.results[0];
            console.log(monkey_sh);
    
            // 动态生成monkey_sh table中的数据
            $("#pre_alpha_monkey_sh_table").dataTable().fnClearTable();     //清空一下table
            $("#pre_alpha_monkey_sh_table").dataTable().fnDestroy();        //还原初始化了的datatable
            $("#pre_alpha_monkeysh_tbody").empty();
    
            //for(var i=0;i<monkey_sh.length;i++){
            var $tr = $("<tr></tr>");
            $tr.append("<td>"+monkey_sh.round+"</td>");
            $tr.append("<td>"+monkey_sh.version+"</td>");
            $tr.append("<td>"+monkey_sh.dppm+"</td>");
            $tr.append("<td>"+monkey_sh.samples+"</td>");
            $tr.append("<td>"+monkey_sh.HWT+"</td>");
            $tr.append("<td>"+monkey_sh.SWT+"</td>");
            $tr.append("<td>"+monkey_sh.FatalJE+"</td>");
            $tr.append("<td>"+monkey_sh.FatalNE+"</td>");
            $tr.append("<td>"+monkey_sh.KE+"</td>");
            $tr.append("<td>"+monkey_sh.JE+"</td>");
            $tr.append("<td>"+monkey_sh.NE+"</td>");
            $tr.append("<td>"+monkey_sh.ANR+"</td>");
            $("#pre_alpha_monkeysh_tbody").append($tr);
    		//}
    
          	//dataTable重新渲染
          	$("#pre_alpha_monkey_sh_table").dataTable({
                language: {
                  url:"dist/zh_CN.json"
                },
                 "aLengthMenu" : [3, 16, 32, 64], //更改显示记录数选项
                 "iDisplayLength" : 3, //默认显示的记录数
                 "lengthChange": false,
                 "searching": false,
             });
          },
          error: function (msg) {
            alert("网络延迟,请待会加载......");
          }
      });
    })
    
  • 相关阅读:
    luogu P3375 【模板】KMP字符串匹配
    leetcode[129]Sum Root to Leaf Numbers
    leetcode[130]Surrounded Regions
    leetcode[131]Palindrome Partitioning
    leetcode[132]Palindrome Partitioning II
    leetcode[133]Clone Graph
    leetcode[134]Gas Station
    leetcode[135]Candy
    leetcode[136]Single Number
    leetcode[137]Single Number II
  • 原文地址:https://www.cnblogs.com/itzlg/p/12436019.html
Copyright © 2011-2022 走看看