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: [[ 0, "desc" ],[ 1, "asc"]], //取消默認排序查詢,否則複選框一列會出現小箭頭
    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', width: "60px", defaultContent: "<i></i>"},
      { data: 'totalCases', width: "120px", defaultContent: "<i></i>"},
      { data: 'failCases', width: "120px", defaultContent: "<i></i>"},
      { data: 'passRate', width: "120px", defaultContent: "<i></i>"},
      { data: 'detail', width: "120px", defaultContent: "<i></i>"},
      { data: 'loginfo', width: "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="width: 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("網絡延遲,請待會加載......");
      }
  });
})

參考鏈接

https://www.cnblogs.com/We612/p/10143584.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章