datatables使用服務器端分頁、排序、搜索功能(PHP)


  datatables可以自動幫我們實現分頁,但當數據量過萬時,datatables顯示數據會很慢,因為datatables每取出一條數據,就要創建 tr/td ,所以數據越多,速度就越慢(我5萬條數據大概需要40秒)。

  datatables的服務端模式可以解決這個問題。客戶端模式是一次性把數據加載到前台渲染,很耗時間,服務端模式,根據分頁到后台提取相應的數據。

  使用服務端模式一般需要配置下面的一些參數,案例:

<!DOCTYPE html>
<html>
<head>
    <title>測試datatables服務端</title>
    <link rel="stylesheet" type="text/css" href="__ADMIN__/css/jquery.dataTables.css">
    <!-- jQuery -->
    <script type="text/javascript" charset="utf8" src="__ADMIN__/js/jquery.js"></script>
    <!-- DataTables -->
    <script type="text/javascript" charset="utf8" src="__ADMIN__/js/jquery.dataTables.js"></script>
</head>
<body>
    <table id="table_id_example" class="display">
    <thead>
        <tr>
            <th>user_id</th>
            <th>username</th>
            <th>email</th>
        </tr>
    </thead>
    <tbody>
    <!-- 由datatables自動添加 tr、td -->
    </tbody>
</table>

<script>
$(document).ready(function() {
    $("#table_id_example").dataTable({
      "lengthMenu": [
          [4,8,10,15,20,-1],    // 具體的數量
          [4,8,10,15, 20,"全部"] // 文字描述
      ],
      "paging": true,    // 是否開啟分頁功能(默認開啟)
      'info': true,      // 是否顯示分頁的統計信息(默認開啟)
      "searching":true,  // 是否開啟搜索功能(默認開啟)
      "ordering": true,  // 是否開啟排序功能(默認開啟)
      "order":[ [0,'asc'] ], // 設置默認排序的表格列[參數1是表格列的下標,從0開始]
      "stateSave": true,      // 是否保存當前datatables的狀態(刷新后當前保持狀態)
      "processing"true,     // 顯示處理中的字樣[數量多的時候提示用戶在處理中](默認開啟)
      "serverSide": true,    // 是否開啟服務器模式
                              // false時,會一次性查詢所有的數據,dataTables幫我們完成分頁等。
                              // true時,點擊分頁頁碼就會每次都到后台提取數據。
      "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": "末頁"  
            },  
            "oAria": {  
                "sSortAscending": ": 以升序排列此列",  
                "sSortDescending": ": 以降序排列此列"  
            }  
          },
      // 使用ajax到后台服務獲取數據
      "ajax": {               
      "url": "{:url('User/index')}", //請求數據的后台地址
      "type": "POST",     // ajax的請求方法
          
      },
      //需要接收返回的數據
      //總的數量與表格的列數必須一致,不能多也不能少,一個變量代表一個td
      //如果data接收服務器沒有返回該字段信息,那么該字段一定要同時設置defaultContent屬性
      //例{'data':'a',"defaultContent":""},
      "columns": [
        {"data": "user_id"},
        {"data": "username"},
        {"data": "email"},
      ]
    });
  });
</script>
</body>
</html>

   上面的設置好之后,給服務端發送ajax請求,我們可以在瀏覽器的控制台看到ajax請求的數據如下:

  

  我們可以在服務端接收這些數據,由於接收到的是一個多維數組,拆分數據的時候注意一下即可。以下是PHP中TP5框架處理服務端數據的案例:

if( request()->isAjax() ){
            $this->user = new UserModel;

            //接收所有傳過來的post數據
            $datatables = request()->post();
            //得到排序的方式
            $order = $datatables['order'][0]['dir'];
            //得到排序字段的下標
            $order_column = $datatables['order'][0]['column'];
            //根據排序字段的下標得到排序字段
            $order_field = $datatables['columns'][$order_column]['data'];
            //得到limit參數
            $limit_start = $datatables['start'];
            $limit_length = $datatables['length'];
            //得到搜索的關鍵詞
            $search = $datatables['search']['value'];

            //從數據庫取出結果
            //如果有搜索行為,則按照關鍵詞查詢數據
            if ($search) {
                $data = $this->user
                        ->order("$order_field $order")
                        ->limit($limit_start,$limit_length)
                        ->where('user_id','LIKE',"%$search%")
                        ->select();
                $data_keyword = $this->user
                                ->where('user_id','LIKE',"%$search%")
                                ->select();
                $cnt = count($data_keyword);   //獲取滿足關鍵詞的總記錄數

            }else{
                //沒有關鍵詞,則查詢全部
                $data = $this->user
                ->order("user_id $order")
                ->limit($limit_start,$limit_length)
                ->select();
                $cnt = $this->user->count(); // 數據總數
            }

            if($data) {
                $data = collection($data)->toArray();
            }            
            $info = [
               'draw'=> request()->post('draw'), // ajax請求次數,作為標識符
               'recordsTotal'=>count($data),  // 獲取到的結果數(每頁顯示數量)
               'recordsFiltered'=>$cnt,       // 符合條件的總數據量
               'data'=>$data,          //獲取到的數據結果
            ];
            //轉為json返回
            return json( $info );

  如果不會TP5框架或者使用其他編程語言,這里有通用的思路。

  因為現在是后端模式,一些業務邏輯需要我們去處理:

  1.從ajax中接收到必要的數據,如果需要用到分頁,需要查數據庫的limit函數的開始、結束參數;要實現排序,則需要獲取排序的字段、排序的方式;要加上搜索功能,就要獲取到搜索的關鍵字。

  2.要做是否有搜索行為的判斷,有搜索關鍵字就用到where語句將關鍵字查出,沒有則直接查出返回結果即可。比較直白的邏輯:將這些數據整合到sql查詢語句中,需要排序就用order,需要分頁就加上limit,需要搜索就加where條件判斷

  3.由於要返回符合條件的總數量,搜關鍵詞跟查詢所有數據獲得的數據量肯定不同,所以要分來獲取;搜關鍵詞的時候要查詢2次數據庫,一次是查出帶limit的結果,一次是查出帶關鍵詞的結果

  4.查關鍵詞不會得到查哪個字段,只能自己通過程序判斷出來,所以最好只查一個字段的關鍵詞

  5.最后的返回數據是核心,‘draw’要原樣返回,'data'是從數據庫中獲取到的數據,轉為json格式返回給datatables。

  附:

  datatables簡單使用


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM