• Datatables 在asp.net mvc中的使用


    前言

    最近使用ABP(ASP.NET Boilerplate)做新项目,以前都是自己扩展一个HtmlHelper来完成同步/异步分页,但是有个地方一直不满意,排序太费劲。
    以前接触过一点点的Datatables,知道它的排序非常方便,点击表头即可排序,还支持多列排序,然后就把Datatables集成到项目里了。

    Datatables简介

    Datatables(以下简称dt)是一款jquery表格插件。它是一个高度灵活的工具,可以将任何HTML表格添加高级的交互功能。 点击进入Datatables中文网

    • 分页,即时搜索和排序
    • 几乎支持任何数据源:DOM, javascript, Ajax 和 服务器处理
    • 支持不同主题 DataTables, jQuery UI, Bootstrap, Foundation
    • 各式各样的扩展: Editor, TableTools, FixedColumns ……
    • 丰富多样的option和强大的API
    • 支持国际化
    • 超过2900+个单元测试
    • 免费开源 ( MIT license )!
    • 更多特性请到Datatables中文网查看看

    与Asp.Net Mvc(以下简称mvc)结合使用

    本文重点讲解dt在mvc(此处应该吐槽webform)中的使用。其他语言也是差不多的用法。

    初始化Datatables

    引入js和css

    //bootstrap的css
    <link href="~/Content/bootstrap.min.css" rel="stylesheet"/>
    //这里我们使用bootstrap的主题,其他的请对号入座
    <link href="~/Scripts/DataTables-1.10.10/media/css/dataTables.bootstrap.min.css" rel="stylesheet" />
    
    //jquery
    <script src="~/Scripts/jquery-1.10.2.min.js"></script>
    //bootstrap主题的js
    <script src="~/Scripts/DataTables-1.10.10/media/js/jquery.dataTables.min.js"></script>
    //核心js
    <script src="~/Scripts/DataTables-1.10.10/media/js/dataTables.bootstrap.js"></script>
    //自定义的js,修改dt默认的一些配置(如中文提示)
    <script src="~/Scripts/DataTables.js"></script>
    
    //DataTables.js  这是Datatables的相关知识,具体作用请求官网查看
    $.extend($.fn.dataTable.defaults, {
        "dom": "<'row'<'col-sm-12'tr>>" +
                "<'row'<'col-sm-12 text-center'i>>" +
                "<'row'<'col-sm-5'l><'col-sm-7'p>>",//默认是lfrtip
        "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": ": 以降序排列此列"
            }
        }
    });
    

    初始化dt

    dt支持多种数据源,在此我们只说“服务器处理”。
    服务器处理的代码如下(有些默认配置已经在上面的DataTables.js中配置,如开启服务器模式"serverSide": true):

    <table id="area" class="table" data-order="[[0,&quot;desc&quot;]]" 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);
                    }
                }
            });
        });
    </script>
    
    

    dataTable和DataTable的区别

    1.10.x版本后,有两种初始化的写法, $().dataTable() 返回的是一个jQuery实例, $().DataTable() 返回的是Datatables的api实例, 如果在使用过程中出现某某方法不存在不支持之类的,一般都是由于是用第一种方法初始化dt,用返回的对象去调用api的方法,所以报错误。
    dt的api实例和jquery可以互转 ,jquery转api:dt.api();api转jquery:dt.to$(); 详细参考 api手册

    服务器端获取Datatables的请求参数

    当使用服务器处理时,dt会发送如下数据给服务器

    名称 类型 描述
    draw integerJS 请求次数计数器,每次发送给服务器后又原封返回.
    start integerJS 第一条数据的起始位置,比如0代表第一条数据
    length integerJS 每页显示的条数.
    search[value] stringJS 全局的搜索条件,针对于每一列( searchable需要设置为 true )
    search[regex] booleanJS 如果为 true代表全局搜索的值是作为正则表达式处理,为 false则不是。
    order[i][column] integerJS i是一个数组索引,对应的是 columns,从0开始,次参数表示那一列需要排序
    order[i][dir] stringJS 上面确定了是那一列,这个确定对应的列是什么样的排序方式 desc 是降序 asc升序
    columns[i][data] stringJS columns 绑定的数据源,由 columns.data 定义
    columns[i][name] stringJS columns.name 里定义的名称
    columns[i][searchable] booleanJS 标记列是否能被搜索 为 true代表可以,否则不可以,这个是由 columns.searchable 控制
    columns[i][orderable] booleanJS 标记列是否能排序 为 true代表可以,否则不可以,这个是由 columns.orderabl 控制
    columns[i][search][value] stringJS 特定列的搜索条件
    columns[i][search][regex] booleanJS 特定列的搜索条件是否视为正则表达式

    可以看到,请求的参数还是很规则的。
    我们可以使用Request.Form(post方式),Request.QueryString(get方式)或者Request.Params/Request获取请求参数,但是如果这么做就太low了,每个方法都要写一大堆的Request那还不如不用呢。
    幸好,我们有ModelBinder

    使用asp.net mvc的ModelBinder(模型绑定)自定绑定请求的参数

    上文讲到如果使用Request的方式我们还不如不用,那么我们这里就用到了ModelBinder(其实也是对Request进行了封装),我们可以用一个类还接收所有的请求参数,如下所示:

    public JsonResult GetDatas(DataTablesParameters query)
    {
    }
    

    下面我们开始编写这个类。
    此处的排序只实现了单列排序,如需多列排序请自行修改

    /// <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的时候,我们使用这个类(或这个类的派生类)来接收请求参数。

    返回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; }
    

    调用

    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 Json(resultJson);
    

    渲染Table,展示数据

    服务器已经返回了我们想要的Json数据,这时候我们就要开始渲染Table,让它将数据显示正常了。

    dt的渲染方式主要有js渲染和html的data-属性来渲染,我选择使用data-属性来渲染(即初始化的时候的table)。

    Table的data-data属性要和返回的实体类的属性对应,否则渲染不上

    添加行操作

    我们需要在每行的后面加上诸如“修改”,“审核”,“删除”等等的操作按钮,在dt里怎么操作呢?
    其实很简单。

    table的表头最后一行加如下代码:

    <th data-orderable="false">操作</th>
    

    在dt初始化的时候添加如下代码:

           "columnDefs": [
                {
                    "targets": -1,//-1表示最后一行
                    "width": "100px",
                    render: function (data, type, full, meta) {
                        return '<a class="btn btn-sm btn-info" href="javascript:;">设置<i class="fa fa-cogs"></i></a>  ' +
                            '<a class="btn btn-sm btn-info" href="javascript:;">删除<i class="fa fa-trash"></i></a>';
                    }
                }]
    
    

    效果图

    效果图

    源码

    源码

    具体位置在项目MvcDemo的Controller里

    作者:醉丶千秋
    声明1:除特殊说明外均为原创博客。原创博客转载时请在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    声明2:本文排版修改自 tkb至简

  • 相关阅读:
    (*^_^*)Pose Estimation:DensePose
    (^_^)Pose Estimation:SamplePose
    [*v*/]人脸识别任务算法RetinaFace
    [*v*/]人脸识别任务算法MTCNN
    从Winograd算法看INT8量化及卷积加速原理
    [*_*/]Darknet && Mobilnet
    从TensorRT看INT8量化原理
    SSD算法精度
    信用评分卡模型的理论准备
    分类模型评估指标
  • 原文地址:https://www.cnblogs.com/chiakiyu/p/5436899.html
Copyright © 2020-2023  润新知