上一篇隨筆提到了MvcPager,最近用到了一款前端JQ插件------DataTable(簡稱DT),很好用。
DT是一款前端插件,和后端完全分離開,就這點來看,我就特別喜歡。
一.使用DT,需要以下支持
js:jq+jquery.dataTables.min.js
二、頁面上進行引入js,直接使用DT功能
前端代碼:

1 @{ 2 Layout = null; 3 } 4 <!DOCTYPE html> 5 6 <html> 7 <head> 8 <meta charset="utf-8"> 9 <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 10 <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" /> 11 <title>用戶列表</title> 12 <link href="~/Content/Scripts/h-ui/css/H-ui.min.css" rel="stylesheet" /> 13 <link href="~/Content/Scripts/h-ui.admin/css/H-ui.admin.css" rel="stylesheet" /> 14 <link href="~/Content/Scripts/Hui-iconfont/1.0.8/iconfont.css" rel="stylesheet" /> 15 16 <style> 17 .page-container { 18 padding: 10px; 19 } 20 21 .operation { 22 background: #EFEEF0; 23 padding: 3px; 24 } 25 26 .search { 27 background: #EFEEF0; 28 padding: 5px; 29 margin-top: 5px; 30 } 31 32 .table { 33 margin-top: 10px; 34 } 35 36 .dataTables_info { 37 margin-left: 5px; 38 } 39 40 #table1_info { 41 padding: 0; 42 } 43 44 #table1_length { 45 margin-left: 15px; 46 } 47 </style> 48 <!--引入腳本解決兼容性(hack技術,必須放入head中)--> 49 <!--[if lt IE 9]> 50 <script src="~/Content/Scripts/html5_css3/html5shiv.min.js"></script> 51 <script src="~/Content/Scripts/html5_css3/respond.min.js"></script> 52 <script src="~/Content/Scripts/PIE-2.0beta1/PIE_IE678.js"></script> 53 <![endif]--> 54 </head> 55 <body> 56 <div class="page-container"> 57 <div class="operation"> 58 <a class="btn btn-danger radius" href="javascript:;"><i class="Hui-iconfont"></i> 批量刪除</a> 59 <a class="btn btn-primary radius" href="javascript:;"><i class="Hui-iconfont"></i> 添加用戶</a> 60 </div> 61 62 <div class="search"> 63 <input type="text" id="nickname" class="input-text" style="width:100px;" placeholder="昵稱"> 64 <button id="search" class="btn btn-success" type="submit"><i class="Hui-iconfont"></i> 查詢</button> 65 </div> 66 67 <div class="table"> 68 <table id="table1" class="table table-border table-bordered table-bg table-hover"> 69 <thead> 70 <tr class="text-c"> 71 <th><input type="checkbox" name="" value=""></th> 72 <th>昵稱</th> 73 <th>賬號</th> 74 <th>密碼</th> 75 <th>添加時間</th> 76 <th>修改時間</th> 77 <th>是否禁用</th> 78 <th>操作</th> 79 </tr> 80 </thead> 81 </table> 82 </div> 83 </div> 84 </body> 85 </html> 86 <script src="~/Content/Scripts/jquery-2.0.3.min.js"></script> 87 <script src="~/Content/Scripts/datatables/1.10.13/jquery.dataTables.min.js"></script> 88 <script src="~/Content/Scripts/h-ui/js/H-ui.js"></script> 89 <script src="~/Content/Scripts/h-ui.admin/js/H-ui.admin.js"></script> 90 91 <script type="text/javascript"> 92 var table1 = null; 93 $(function() { 94 table1=initializeTable(); 95 $("#search").click(function() { 96 table1.ajax.reload(); 97 }); 98 }); 99 100 function initializeTable() {//初始化table 101 var table = $("#table1").DataTable({ 102 /****************************************表格數據加載****************************************************/ 103 "serverSide": true, 104 "ajax": {//ajax請求數據源 105 "url": "/UserInfo/Manager/Search", 106 "type": "post", 107 "data": function (data) {//添加額外的數據給服務器 108 data.pageIndex = (data.start / data.length) + 1; 109 data.nickname = $("#nickname").val().trim(); 110 } 111 }, 112 "columns": [//列綁定 113 { "defaultContent": "" }, 114 { "data": "Nickname" }, 115 { "data": "LoginName" }, 116 { "data": "LoginPassword" }, 117 { "data": "AddTime" }, 118 { "data": "ModifyTime" }, 119 { "data": "IsForbidden" }, 120 { "defaultContent": "" } 121 ], 122 "columnDefs": [//列定義 123 { 124 "targets": [0], 125 "data": "UserInfoId", 126 "render": function (data, type, full) {//全部列值可以通過full.列名獲取,一般單個列值用data PS:這里的render是有多少列就執行多少次方法。。。不知道為啥 127 return "<input type='checkbox' value='" + data + "' name='UserInfoId'>"; 128 } 129 }, 130 { 131 "targets": [4], 132 "data": "AddTime", 133 "render": function (data, type, full) {//全部列值可以通過full.列名獲取,一般單個列值用data PS:這里的render是有多少列就執行多少次方法。。。不知道為啥 134 if (data == null || data.trim() == "") { return ""; } 135 else { var date = new Date(parseInt(data.slice(6))); return date.getFullYear() + "/" + date.getMonth() + "/" + date.getDate(); } 136 } 137 }, 138 { 139 "targets": [5], 140 "data": "ModifyTime", 141 "render": function (data, type, full) {//全部列值可以通過full.列名獲取,一般單個列值用data PS:這里的render是有多少列就執行多少次方法。。。不知道為啥 142 if (data == null || data.trim() == "") { return "/"; } 143 else { var date = new Date(parseInt(data.slice(6))); return date.getFullYear() + "/" + date.getMonth() + "/" + date.getDate(); } 144 } 145 }, 146 { 147 "targets": [6], 148 "data": "IsForbidden", 149 "render": function (data, type, full) {//全部列值可以通過full.列名獲取,一般單個列值用data PS:這里的render是有多少列就執行多少次方法。。。不知道為啥 150 if (data) { return "是"; } 151 else { return "否"; } 152 } 153 }, 154 { 155 "targets": [7], 156 "data": "UserInfoId", 157 "render": function (data, type, full) {//全部列值可以通過full.列名獲取,一般單個列值用data PS:這里的render是有多少列就執行多少次方法。。。不知道為啥 158 return "<a style='text-decoration:none' class='ml-5 f-14' onclick=article_edit('資訊編輯','article-add.html','" + data + "') href='javascript:;' title='編輯'><i class='Hui-iconfont'></i></a>" + 159 "<a style='text-decoration:none' class='ml-5 f-14' onclick=article_del(this,'" + data + "') href='javascript:;' title='刪除'><i class='Hui-iconfont'></i></a>"; 160 } 161 }, 162 163 { "orderable": false, "targets": [0, 7] },// 是否排序 164 //{ "visible": false, "targets": [3, 5] }//是否可見 165 ], 166 "rowCallback": function (row, data, displayIndex) {//行定義 167 $(row).attr("class", "text-c"); 168 }, 169 "initComplete": function (settings, json) { //表格初始化完成后調用 170 171 }, 172 /****************************************表格數據加載****************************************************/ 173 /****************************************表格樣式控制****************************************************/ 174 "dom": "t<'dataTables_info'il>p",//表格布局 175 "language": {//語言國際化 176 "lengthMenu": "每頁 _MENU_ 條", 177 "zeroRecords": "沒有找到記錄", 178 "info": "當前顯示 _START_ 到 _END_ 條,共 _TOTAL_條", 179 "infoEmpty": "無記錄", 180 "paginate": 181 { 182 "first": "首頁", 183 "previous": "前一頁", 184 "next": "后一頁", 185 "last": "末頁" 186 } 187 }, 188 "pagingType": "full_numbers",//分頁格式 189 "processing": true,//等待加載效果 190 "ordering": false,//排序功能 191 /****************************************表格樣式控制****************************************************/ 192 }); 193 return table; 194 } 195 </script>
后端代碼:

1 /****************Controller后台代碼******************/ 2 public ActionResult Search(DataTable dt,string nickname) 3 { 4 int total; 5 int pageSize = dt.length; 6 int pageIndex = dt.pageIndex; 7 8 IQueryable<Model.UserInfo> userInfoIq=CurrentBllSession.UserInfoBll.GetIQueryableBySearchPage(pageIndex,pageSize,out total,nickname); 9 List<Model.UserInfo> userInfoList = userInfoIq.ToList(); 10 dt.recordsTotal = total; 11 dt.recordsFiltered = total ; 12 dt.data = userInfoList; 13 14 return Json(dt); 15 } 16 17 18 /**************************Bll服務代碼************************/ 19 public IQueryable<UserInfo> GetIQueryableBySearchPage(int pageIndex,int pageSize,out int total,string nickname) 20 { 21 IQueryable<UserInfo> userInfoIq= CurrentDal.GetIQueryable(); 22 23 if (!string.IsNullOrEmpty(nickname)) 24 { 25 userInfoIq=userInfoIq.Where(a => a.Nickname.Contains(nickname)); 26 } 27 total=userInfoIq.Count(); 28 userInfoIq=userInfoIq.OrderByDescending(a => a.AddTime); 29 userInfoIq=userInfoIq.Skip((pageIndex - 1)*pageSize).Take(pageSize);//分頁前必須排序,不然EF報錯 30 31 return userInfoIq; 32 }

1 using System; 2 using System.Collections; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Text; 6 7 namespace ViewModel 8 { 9 /// <summary> 10 /// JqueryDataTable插件交互的DT格式的數據(DT參數區分大小寫) 11 /// </summary> 12 public class DataTable 13 { 14 /// <summary> 15 /// 請求次數(前端==》后端) 16 /// </summary> 17 public int draw { get; set; } 18 19 /// <summary> 20 /// 總記錄數(前端《==后端) 21 /// </summary> 22 public int recordsTotal { get; set; } 23 24 /// <summary> 25 /// 過濾后的總記錄數(前端《==后端) 26 /// </summary> 27 public int recordsFiltered { get; set; } 28 29 /// <summary> 30 /// 記錄開始索引(前端==》后端) 31 /// </summary> 32 public int start { get; set; } 33 34 /// <summary> 35 /// PageIndex(前端==》后端) 36 /// </summary> 37 public int pageIndex { get; set; } 38 39 /// <summary> 40 /// PageSize(前端==》后端) 41 /// </summary> 42 public int length { get; set; } 43 44 /// <summary> 45 /// 集合分頁數據(前端《==后端) 46 /// </summary> 47 public IList data { get; set; } 48 } 49 }
這樣就搞定了。。。是不是很簡單(● ̄(エ) ̄●)
╮(╯_╰)╭好的,我來解釋下。
前台:
首先我們的table只是給出了thead部分,那么tbody部分呢?交給DT來完成,由DT來控制。那么我們先來初始化DT,js會調用initializeTable()方法,方法里調用$("#table1").DataTable({各種配置});來配置DT。至於這些配置的作用,我代碼里都做了注釋,詳細的配置解釋,可以查看官網的文檔。
配置里有一項很重要,就是ajax配置項,這里是數據源的配置項,數據源可以有多種,我這里選用了ajax異步請求數據源。
"url": "/UserInfo/Manager/Search"這個是配置了DT請求數據的url地址
"type": "post"指明了以post方式發送請求
"data": function (data) {//添加額外的數據給服務器
data.pageIndex = (data.start / data.length) + 1;
data.nickname = $("#nickname").val().trim();
}這了由於我用到了搜索的功能,所以每次請求數據的時候,要把搜索的條件作為附加的數據傳給服務器
最后,注意要加上"serverSide": true,因為我們的數據都是從后台過來的,不是前台的靜態數據,要開啟“服務器模式”,這樣,你每次對表格的操作,都會變成一次次的請求發送給服務器。
后台:
后台負責提供數據源,使用自定義的DataTable類來作為格式化的數據進行交互。當然這里的DataTable類不是必須的,你只要滿足前后數據交互的格式就可以,這里封裝成一個類,是為了方便。
DT建議我們交互的數據格式,最起碼要包含以下幾項,我用匿名類來表示(區分大小寫):
new {
draw=***,
recordsTotal=***,
recordsFiltered=***,
data=***,
}
其他項的話,你可以根據自己的實際情況自行添加。
准備好了數據之后呢,把數據Json序列化后,返回給前端,即可。
效果圖: