jQuery DataTables 的几个坑,异步加载(服务器)、监听、重载等等

  今天真的被这破插件气疯了,于是有了下面的截图。此文不定期更新,要是有新坑欢迎来填。

jQuery DataTables 的几个坑,监听、重载等等

看看截图娱乐娱乐

图1

图2

图3

图4

好了,正事儿要紧,先来说说这玩意儿的加载过程

  1. 首先必不可少的 jQueryDataTables.jsDataTables.css 的引入略过

  2. 我们先手写好一张 table 表格,大概就像下面这样

    <!-- 我就写简单点,去掉了所有 class,根据样式自己添加 -->
    <table id="user-list">
    <thead>
        <tr>
            <th>ID</th>
            <th>账号</th>
            <th>用户组</th>
            <th>账号状态</th>
            <th>添加时间</th>
            <th>操作</th>
        </tr>
    </thead>
    <!-- tbody 这儿留空,依靠 Ajax 返回的数据填充 -->
    <tbody></tbody>
    </table>
  3. 来吧,先大概写个 JS

    说一下,下方的一些参数,大家在网上可能经常看到 ab 开头的写法,那是旧式写法,当然是不影响使用的,推荐用新驼峰写法。对应表:Datatables | 升级 | 1.10.x与1.9.x参数名对照表

    // 根据上面的 HTML 代码操作,上方已定义 table 的 id 为 user-list
    var table = $('#user-list');
    table.dataTable({
        /**
         * 分页的几个显示方式,大致翻译一下
         * `numbers` - 仅含页码按钮
         * `simple` - 仅含“上一页”和“下一页”
         * 'simple_numbers` - “上一页”和“下一页”,加上页码
         * `full` - “首页”,“上一页”,“下一页”,“尾页”按钮
         * `full_numbers` - “首页”,“上一页”,“下一页”,“尾页”按钮以及页码
         * `first_last_numbers` - “首页”和“尾页”按钮,加上页码
         */
        pagingType: 'full_numbers', // 所以这儿我用了 full_numbers
        lengthMenu: [10, 15, 20],   // 可选每页显示数量
        serverSide: true, // 服务端分页
        searching: true,  // 过滤功能
        ordering: true,   // 排序功能
        columnDefs: [{
            orderable: false,
            targets: [1, 2, 5] // 指定不排序列,下标 0(比如 ID,从 0 开始数,此处帐号、用户组和操作不能排序)
        }],
        language: {
            url: '/assets/js/plugins/datatables/Chinese.json' // 语言文件,下方会贴出来
        },
        ajax: {
            url: '',     // 异步请求地址,没啥好说的
            type: 'get', // 请求方式,因为是取数据,所以我选择了 get
            data: ''     // 额外请求参数,一般是不需要的
        },
        // 暂时先写这部分,下部分再慢慢道来
    });
  4. 官方对于服务器端的说明在这儿:服务器处理(server-side) 手册 Datatables 中文网

    当然了,爱看不看…从“服务器需要返回的数据(Returned data)”这一段(上方链接带上了锚点,访问即可到达),我们可以看到服务端需要返回什么数据:

    名称 类型 简述
    draw integer|JS DataTables 每次发送请求会带上这个参数,接收到以后转成 int 类型返回去就行。PHP 直接 intval($draw) 非常方便
    recordsTotal integer|JS 总记录数(未过滤)
    recordsFiltered integer|JS 记录数(已过滤/检索)
    data array|Type 重点数据,靠这玩意儿完成数据填充
    error string|JS 可选:这个参数用于异常时返回一个提示
    - - 下方是额外参数,爱看不看 too。下方参数要放进 data 里数组的每一个元素内(不明白?没事…后面有示例)
    DT_RowId string|JS 表格每行数据,也就是 <tr> 上加一个 ID
    DT_RowClass string|JS 同上 <tr> 加一个 class 样式
    DT_RowData object|JS 扔一点数据到 columns.renderrow 参数里
    DT_RowAttr object|JS <tr> 添加一个属性,例如 <tr data-val="what">
    - - 这部分额外参数通过服务端传入,并自动绑定。无需额外操作
  5. 通过上方表格的简述,我们知道了 DataTables 需要从服务端返回什么数据,下面就是一个简单的数据格式返回,代码为“拍黄片” PHP

    // 假设我们已经从数据库拿到用户列表并存入了变量 $userList
    // 在这儿先对数据进行一次处理,便于前端显示
    foreach ($userList as $key => $val) {
        $userList[$key]['DT_RowClass'] = "text-center"; // 可忽略这个
        $userList[$key]['add_time'] = date('Y-m-d H:i', $val['add_time']); // 格式化时间
        $userList[$key]['operate'] = [ // 解释一下这个,因为我们 HTML 中最后一列是操作,含有编辑和删除功能,数据库肯定是没有这个相关数据的,我们模拟一个 `operate` 列出来。放入 ID 是因为我们编辑和删除需要这货啊!
            'id' => $val['id']
        ];
    }
    $data = [
        // 前面说了这个按照接收数据来返回,为了防止 XSS 攻击
        // 我这儿就没详写,因为我用 Laravel 框架这儿直接 $request->draw
        'draw' => 1,
        // 用户数据存入 data
        'data' => $userList,
        // 总记录数(不过滤)
        'recordsTotal' => $count, // 实际有多少就是多少
        // 记录数(已过滤)
        'recordsFiltered' => $filteredCount // 经过检索/过滤后的
    ];
    if (!$userList) {
        $data['error'] = '这儿什么也没有';
    }
    // 实际上...在 Laravel 框架中直接 return $data 会自动变成 Json,嘿...嘿嘿嘿
    return json_encode($data);

    这儿再说一下排序,我是这么做的。还是爱看不看…

    // 依旧是 Laravel 框架,$request->order 这个可以看成 _GET['order']
    // 接收请求拿到 DataTables 传过来的 order
    $order = $request->order;
    // 将排序字段名和值组合成新数组
    $order = [
        $request->columns[$order[0]['column']]['data'] 
            => $order[0]['dir']];
    // 此时的 $order 是一个数组,形式为 id => desc。原谅没有加引号,不然这段代码颜色会错
    // 在写取数据方法的时候建议给 $order 一个默认值
  6. 现在数据拿到了,再来处理处理第 3 步未完成的 JS

    // 其实也就是再加一个 columns。注意下方代码和第 3 步是衔接的
    columns: [
        // 这里 data 后的值如果 SQL 语句正常默认就是字段名
        {data: 'id'},
        {data: 'username'},
        {   // 这里也是一段重要的说明,如下代码,我数据库内 status 状态存的数字
            // 在这儿总不能显示 0 和 1 吧?我们需要通过 render 方法来执行一些数据处理
            // 当然也可以加一些样式在这个地方,文章末尾会有截图可供参考
            data: 'status', render: function (data) {
                var content;
                switch (data) {
                    case 0:
                        content = '已禁用';
                        break;
                    case 1:
                        content = '正常';
                        break;
                    case -1:
                        content = '已删除';
                        break;
                }
                return content;
            }
        },
        {data: 'add_time'},
        {
            // 对了,前文的额外参数 DT_RowData,在下行 function 括号内的第三个参数可以获取。
            // 当然我前面并没有传入这个数据,所以下行的 type 和 row 并未使用,可删除
            data: 'operate', render: function (data, type, row) {
                // TODO: return(string);
                /*
                 这里的代码我就不写上来了,关于操作前面说了就是两个按钮,一个编辑一个删除
                 每个人的样式不一样,而我前面的 PHP 代码里给 data 传了一个 ID
                 此处可以通过 data.id 得到其值
                 类似这样:return '<button data-id="' + data.id + '"></button>';
                 至此,数据已经可以拿到并成功显示啦!
                 */ 
            }
        }
    ]

    低调上图:(文中精简了不少东西嘛,使用 BootStrap 样式更佳哦~)
    成功截图

Emmm…一不小心就把这货写清楚了

这儿说说我遇到的几个坑:

  • 首先第一个!不要去重复 table.dataTable({});。不然就是一个弹框提示你无法重新初始化,顶部图1的由来。

  • 前文说到我的最后一列是两个按钮,我尝试过用 $('table tbody button').click(); 的方式,根本监听不了,最后发现要用 on,也就是

    // table 为之前用于初始化 DataTables 的那个,等于上文已存入 table 变量的 $('#user-list') 
    // tbody 这个可以不要,个人习惯精确定位
    // on 后面的第一个参数为事件参数,什么 touch 啊,click 啊之类
    // 第二个就是重点,精确到你要监听事件的控件、标签。例如我要监听按钮就写 tr button
    // 第三个匿名函数没什么好说的
    table.find('tbody').on('click', 'tr button', function (){
        // TODO: ...
        var $this = $(this); // 可以拿到当前操作的对象
    });
  • 再就是所有的 API!必须使用 table.api() 调用

    我最开始看文档的示例:重新加载数据(ajax.reload()) 选项(option) 参考(reference) Datatables 中文网
    MD!这里面根本没写 api() 好吗,最后在 Google 搜索到这篇:table.ajax.reload() is undefined — DataTables forums 才解决…哎!

  • 还有…待更吧…


差点忘了中文语言:

{
  "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": ": 以降序排列此列"
  }
}

猜你喜欢

转载自blog.csdn.net/maxsky/article/details/79822346
今日推荐