随便说说
这篇想记录我在写网站中遇到的很大的一个前端问题,就是如何实现.net core2.1 + datatables 真分页,查了很多资料,结合遇到的问题,总算解决了,特此记录,有更好的方法欢迎指正。
参考资料:https://blog.youkuaiyun.com/mss359681091/article/details/52609221
前端框架
我在本项目中使用的是 H-ui 前端框架 ,推荐下,对于前端小白来说说使用还是很舒服的,有官网,有说明,有样式,不用为前端布局烦恼,安心写后端就好了。网址: http://www.h-ui.net/
Datatables简介
Datatables(以下简称dt)是一款jquery表格插件。它是一个高度灵活的工具,可以将任何HTML表格添加高级的交互功能。 网址:http://datatables.club/
初始化Datatables
新写一个js,专门用来初始化Datatable
//DataTables.js 这是Datatables的相关知识,具体作用请求官网查看
$.extend($.fn.dataTable.defaults, {
"processing": true,//加载中
"serverSide": true,//服务器模式(★★★★★重要,本文主要介绍服务器模式)
"searching": false,//datatables自带的搜索
"scrollX": true,//X滑动条
"pagingType": "full_numbers",//分页模式
"ajax": {
"type": "POST",//(★★★★★重要)
"contentType": "application/json; charset=utf-8"
},
"language": { //使用中文界面
"processing": "加载中...",
"lengthMenu": "每页显示 _MENU_ 条数据",
"zeroRecords": "没有匹配结果",
"info": "显示第 _START_ 至 _END_ 项结果,共 _TOTAL_ 项",
"infoEmpty": "显示第 0 至 0 项结果,共 0 项",
"infoFiltered": "(由 _MAX_ 项结果过滤)",
"infoPostFix": "",
"search": "搜索:",
"url": "",
"emptyTable": "没有匹配结果",
"loadingRecords": "载入中...",
"thousands": ",",
"paginate": {
"first": "首页",
"previous": "上一页",
"next": "下一页",
"last": "末页"
},
"aria": {
"sortAscending": ": 以升序排列此列",
"sortDescending": ": 以降序排列此列"
}
}
});
网页Datatable
dt支持多种数据源,在此我们只说“服务器处理”。
服务器处理的代码如下(有些默认配置已经在上面的DataTables.js中配置,如开启服务器模式"serverSide": true):
<table id="area" class="table" data-order="[[0,"desc"]]" width="100%">
<thead>
<tr>
<th data-data="Id" data-visible="false">Id</th>
<th data-data="Name">名称</th>
<th data-data="Description" data-orderable="false">描述</th>
<th data-data="PointX">X坐标</th>
<th data-data="PointY">Y坐标</th>
</tr>
</thead>
</table>
<script>
$(function(){
var userTable = $('#area').DataTable({
"ajax": {
"url": "@Url.Action("GetDatas")", //这里是请求后端
"data": function(data) {
data.Name = $("#name").val();;//此处是添加额外的请求参数
return JSON.stringify(data);
}
"columnDefs": [{ //收到数据后的处理
"targets": 0,
"width": "3%", //宽度使用百分比
render: function (data, type, full, meta) {
return '<input type="checkbox" id="checkbox-all-' + full.Id+ '" value="' + full.Id+ '" />';
}],
"aaSorting": [[1, "desc"]],//默认第几个排序
},
}
});
});
</script>
后端接收类
接收类可以使用ModelBinder(模型绑定)自定绑定请求的参数的方式,也比较方便。
此处的排序只实现了单列排序,如需多列排序请自行修改
/// <summary>
/// DataTables参数
/// </summary>
public class DataTablesParameters
{
/// <summary>
/// 请求次数计数器
/// </summary>
public int Draw { get; set; }
/// <summary>
/// 第一条数据的起始位置
/// </summary>
public int Start { get; set; }
/// <summary>
/// 每页显示的数据条数
/// </summary>
public int Length { get; set; }
/// <summary>
/// 数据列
/// </summary>
public List<DataTablesColumns> Columns { get; set; }
/// <summary>
/// 排序
/// </summary>
public List<DataTablesOrder> Order { get; set; }
/// <summary>
/// 搜索
/// </summary>
public DataTablesSearch Search { get; set; }
/// <summary>
/// 排序字段
/// </summary>
public string OrderBy
{
get
{
return Columns != null && Columns.Any() && Order != null && Order.Any()
? Columns[Order[0].Column].Data
: string.Empty;
}
}
/// <summary>
/// 排序模式
/// </summary>
public DataTablesOrderDir OrderDir
{
get
{
return Order != null && Order.Any()
? Order[0].Dir
: DataTablesOrderDir.Desc;
}
}
}
/// <summary>
/// 排序
/// </summary>
public class DataTablesOrder
{
/// <summary>
/// 排序的列的索引
/// </summary>
public int Column { get; set; }
/// <summary>
/// 排序模式
/// </summary>
public DataTablesOrderDir Dir { get; set; }
}
/// <summary>
/// 排序模式
/// </summary>
public enum DataTablesOrderDir
{
/// <summary>
/// 正序
/// </summary>
Asc,
/// <summary>
/// 倒序
/// </summary>
Desc
}
/// <summary>
/// 数据列
/// </summary>
public class DataTablesColumns
{
/// <summary>
/// 数据源
/// </summary>
public string Data { get; set; }
/// <summary>
/// 名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 是否可以被搜索
/// </summary>
public bool Searchable { get; set; }
/// <summary>
/// 是否可以排序
/// </summary>
public bool Orderable { get; set; }
/// <summary>
/// 搜索
/// </summary>
public DataTablesSearch Search { get; set; }
}
/// <summary>
/// 搜索
/// </summary>
public class DataTablesSearch
{
/// <summary>
/// 全局的搜索条件的值
/// </summary>
public string Value { get; set; }
/// <summary>
/// 是否为正则表达式处理
/// </summary>
public bool Regex { get; set; }
}
返回Datatables规定的Json
Datatables要求返回的数据Json
名称 | 类型 | 描述 |
---|---|---|
draw | integerJS | 请求次数计数器,每次发送给服务器后又原封返回. |
recordsTotal | integerJS | 即没有过滤的记录数(数据库里总共记录数) |
recordsFiltered | integerJS | 过滤后的记录数 |
data | arrayJS | 表中中需要显示的数据。 |
error | stringJS | 可选。你可以定义一个错误来描述服务器出了问题后的友好提示 |
处理返回的数据
当我们把包含第n页的m数据放在一个List的时候,我们就需要封装以下Datatables想要的数据格式了。
public class DataTablesResult<TEntity>
{
public DataTablesResult(int drawParam, int recordsTotalParam, int recordsFilteredParam, IReadOnlyList<TEntity> dataParam)
{
draw = drawParam;
recordsTotal = recordsTotalParam;
recordsFiltered = recordsFilteredParam;
data = dataParam;
}
public DataTablesResult(string errorParam)
{
error = errorParam;
}
public int draw { get; set; }
public int recordsTotal { get; set; }
public int recordsFiltered { get; set; }
public IReadOnlyList<TEntity> data { get; set; }
public string error { get; set; }
调用
在资料中调用的例子中使用了GetData(),这个函数是用来生成List</TEntity/>数据的,以方便生成前端需要的json格式,在用.net core写 时,生成json 需要用到 Newtonsoft.Json ,如果 List</TEntity/> 中有外联表,则生成json会报错,需要新做一个Models。
public string GetDatas(DataTablesParameters query)
{
var data = new Area().GetData();
if (!string.IsNullOrEmpty(query.Name))
data = data.Where(n => n.Name.Contains(query.Name));
data = data.OrderBy(n=>n.Id);
var count = data.Count();
var result = data.Skip(query.Start).Take(query.Length).ToList();
var resultJson = new DataTablesResult<Area>(draw, recordsFiltered, recordsFiltered, result);
return JsonConvert.SerializeObject(resultJson);
}
渲染Table,展示数据
资料中使用了data-data方式渲染数据,我实际使用中不行,应该还有地方没调整好,我就用了这种方式。
"columnDefs": [{ //收到数据后的处理
"targets": 0,
"width": "3%", //宽度使用百分比
render: function (data, type, full, meta) {
return full.Id;
}],