在项目开发中,偶尔会遇到查询数据过大,超出JSON能够容纳的最大长度,Bootstrap DataTables就无法实现数据加载。此时就需要实现服务器分页功能。不想付费去购买.NET版的,就只有自己手动去完成了。
本篇是在上一篇代码基础上进行修改达到服务器分页效果。
1 结构分析
请求参数说明,做了一个简单的翻译
Parameter name | Type | Description |
---|---|---|
draw |
integer |
Datatables中拉取服务端数据次数 |
start |
integer |
请求数据的开始行数 |
length |
integer |
本次请求数据的多少行数 |
search[value] |
string |
全局搜索值 |
search[regex] |
boolean |
默认‘false’,正则表达式搜索 |
order[i][column] |
integer |
排序的Column行号 |
order[i][dir] |
string |
排序的Column字典集 |
columns[i][data] |
string |
对应Column 第i个的Data,及在指定数据时的赋值字段 |
columns[i][name] |
string |
对应 i 行的Column第i个的名称 |
columns[i][searchable] |
boolean |
设置Column是否可搜索, |
columns[i][orderable] |
boolean |
是否可以排序 |
columns[i][search][value] |
string |
搜索内容 |
columns[i][search][regex] |
boolean |
是否正则表达式搜索 |
响应数据
Parameter name | Type | Description |
---|---|---|
draw |
integer |
Datatables中拉取服务端数据次数,说是防止XSS攻击 |
recordsTotal |
integer |
未做删选前的返回总行数 |
recordsFiltered |
integer ) |
删选之后的总行数 |
data |
array |
返回的data |
error |
string |
异常原因 |
Parameter name | Type | Description |
---|---|---|
DT_RowId |
string |
tr 的ID |
DT_RowClass |
string |
tr 的 class |
DT_RowData |
object |
设置一个Data 集合,方便js事件时使用 |
DT_RowAttr |
object |
给tr 新增一个attributes |
另外几个参数,可以加载到 tr Tag
中
Parameter name | Type | Description |
---|---|---|
DT_RowId |
string |
tr 的ID |
DT_RowClass |
string |
tr 的 class |
DT_RowData |
object |
设置一个Data 集合,方便js事件时使用 |
DT_RowAttr |
object |
给tr 新增一个attributes |
2 前端修改
根据上面的参数,前端需要修改的地方很少,就是在调用插件时新增一个参数 serverSide: true,其他需要的属性看情况使用
function ShowTables(type) {
var actionurl;
actionurl = '@Url.Action("GetEmployeeAuthList", "Employee")';
$('#example tbody').off('click');
$('#example').DataTable().destroy();
var dt = $('#example').DataTable({
ajax: {
type: 'post',
url: actionurl,
dataSrc: 'data',
data: {
Site: $('#Site').val(),
Emplid: $('#Emplid').val(),
Chinam: $('#Chinam').val(),
Neweid: $('#Neweid').val(),
Depcod: $('#Depcod').val(),
DoorGroupID: $('#uDoorGroupID').val(),
},
error: function (xhr, status, error) {
alert(xhr);
}
},
columns: [
{"data": "Site", "name":"公司别",searchable: false },
{ "data": "Emplid", "name": "工号" },
{ "data": "Chinam" ,"name":"姓名" },
{ "data": "Neweid", "name": "卡号" },
{ "data": "Depcod", "name": "Cost Center" },
{ "data": "DoorGroupName", "name": "权限" },
{ "data": "Status", "name":"状态",searchable: false },
{
data: null,
className: "center",
render: function (data, type, row) {
return '<a href="" id="' + data.Neweid + '" class="fa fa-fw fa-lg fa-edit editor_edit"></a>';
}
}
],
select: true,
serverSide: true,//支持服务端分页
processing: true
});
//添加行click事件
$('#example tbody').on('click', 'tr', function () {
dt.$('tr.selected').removeClass('selected');
$('#btnArea').attr('disabled', false);
var rowData = dt.rows(this).data()[0].DT_RowData; //获取后台指定的DT_RowData数据
alert(rowData.Emplid);
//var doorGroupId = $(this).attr('id').split('_')[1];
//var carid = $(this).attr('id').split('_')[2];
}
});
}
3 请求参数处理
需要对请求参数进行解析,实现请求参数的实体类
public class DataTableParms
{
public string draw { get; set; }
public List<DataTableColumns> columns { get; set; }
public DataTableOrder order { get; set; }
public string start { get; set; }
public string length { get; set; }
public DataTableSearch search { get; set; }
}
public class DataTableColumns
{
public string data { get; set; }
public string name { get; set; }
public string searchable { get; set; }
public string orderable { get; set; }
//public DataTableSearch search { get; set; }
}
public class DataTableSearch
{
public string value { get; set; }
public string regex { get; set; }
}
public class DataTableOrder
{
public string column { get; set; }
public string dir { get; set; }
}
解析方法类,采用正则表达式和反射,取出HTTP中的数据进行解析
public class BootStrapDataTable
{
public DataTableParms DeserializePostParms(HttpContextBase content)
{
DataTableParms dtParms = new DataTableParms();
List<DataTableColumns> dtcList= new List<DataTableColumns>();
DataTableSearch dtSearch = new DataTableSearch();
DataTableOrder dtOrder= new DataTableOrder();
try
{
var request = HttpUtility.UrlDecode(content.Request.Form.ToString());
if (!string.IsNullOrEmpty(request))
{
foreach (var Properties in dtParms.GetType().GetProperties())
{
if (Properties.Name.Contains("columns"))
{
Regex indexRegex = new Regex(@"(?:^|/?|&)columns\[\d\]\[data\]=([^&]*)(?:&|$)");
var indexMatch = indexRegex.Matches(request.ToString());
int index = indexMatch.Count;
for (int i = 0; i < index; i++)
{
Regex columnsRegex =
new Regex(string.Format(@"(?:^|/?|&)columns\[{0}\](\[([a-z]*)\])=([^&]*)(?:&|$)", i));
MatchCollection columnsMatch = columnsRegex.Matches(request.ToString());
DataTableColumns dtColumns = new DataTableColumns();
foreach (Match item in columnsMatch)
{
if (item.Success)
{
if (item.Groups.Count == 4)
{
var objTemp = dtColumns.GetType()
.GetProperties()
.FirstOrDefault(w => w.Name.Contains(item.Groups[2].Value));
if (objTemp != null)
{
objTemp.SetValue(dtColumns, item.Groups[3].Value);
}
}
}
}
dtcList.Add(dtColumns);
}
continue;
}
if (Properties.Name.Contains("order"))
{
Regex orderRegex =
new Regex(string.Format(@"(?:^|/?|&)order\[0\]\[([a-z]*)\]=([^&]*)(?:&|$)"));
MatchCollection orderMatch = orderRegex.Matches(request.ToString());
foreach (Match item in orderMatch)
{
if (item.Success)
{
var objTemp = dtOrder.GetType()
.GetProperties()
.FirstOrDefault(w => w.Name.Contains(item.Groups[1].Value));
if (objTemp != null)
{
objTemp.SetValue(dtOrder, item.Groups[2].Value);
}
}
}
continue;
}
if (Properties.Name.Contains("search"))
{
Regex orderRegex =
new Regex(string.Format(@"(?:^|/?|&)search\[([a-z]*)\]=([^&]*)(?:&|$)"));
MatchCollection orderMatch = orderRegex.Matches(request.ToString());
foreach (Match item in orderMatch)
{
if (item.Success)
{
var objTemp = dtSearch.GetType()
.GetProperties()
.FirstOrDefault(w => w.Name.Contains(item.Groups[1].Value));
if (objTemp != null)
{
objTemp.SetValue(dtSearch, item.Groups[2].Value);
}
}
}
continue;
}
Regex urlRegex = new Regex(string.Format(@"(?:^|/?|&){0}=([^&]*)(?:&|$)", Properties.Name));
Match m = urlRegex.Match(request.ToString());
if (m.Success)
{
var objTemp = dtParms.GetType()
.GetProperties()
.FirstOrDefault(w => w.Name.Contains(Properties.Name));
if (objTemp != null)
{
objTemp.SetValue(dtParms, m.Groups[1].Value);
}
}
}
}
dtParms.columns = dtcList;
dtParms.search = dtSearch;
dtParms.order = dtOrder;
}
catch (Exception ex)
{
throw ex;
}
return dtParms;
}
}
4 服务端响应Data
新增一个基类 BaseDataTables
public class BaseDataTables
{
public int draw { get; set; }//
public int recordsTotal { get; set; }//行数
public int recordsFiltered { get; set; }
}
在TEmployeeAuthList类中继承BaseDataTables
public class TEmployeeAuthList:BaseDataTables
{
public List<TEmployeeAuth> data { get; set; }
}
修改TEmployeeAuth.cs 添加DT_RowId ,DT_RowData,需要看具体情况去实现DT_RowData
public class TEmployeeAuth
{
public string DT_RowId { get { return Emplid.ToString() + "_" + DoorGroupID.ToString() + "_" + Neweid.ToString(); } }
public TEmployeeAuth_RowData DT_RowData { get { return new TEmployeeAuth_RowData()
{
DoorGroupID =this.DoorGroupID,
Emplid = this.Emplid,
Neweid = this.Neweid
};} }
public string Site { get; set; }
public string Emplid { get; set; }
public string Chinam { get; set; }
public string Neweid { get; set; }
public string Depcod { get; set; }
public string DoorGroupID { get; set; }
public string Status { get; set; }
public string DoorGroupName { get; set; }
}
public class TEmployeeAuth_RowData
{
public string Emplid { get; set; }
public string DoorGroupID { get; set; }
public string Neweid { get; set; }
}
最后controller 中实现响应Action
public JsonResult GetEmployeeAuthList(string Site, string Emplid, string Chinam, string NeweId, string Depcod, string DoorGroupID, int start, int length)
{
//解析参数
DataTableParms dtParms= new DataTableParms();
BootStrapDataTable objbd= new BootStrapDataTable();
dtParms = objbd.DeserializePostParms(HttpContext);
//声明返回值
TEmployeeAuthList result= new TEmployeeAuthList();
EmployeeBasic employee= new EmployeeBasic();
......略......
return Json(result);
}
以上就是自己实现的服务端分页功能,下一篇记一下自己实现 Bootstrap DataTables的 编辑 功能