dataTables使用心得

来源:互联网 发布:备份数据库怎么还原 编辑:程序博客网 时间:2024/06/01 17:34

由于公司的项目需要用到表格,所以我在网上找了许多的表格插件,对比之下,还是觉得dataTables这个插件比较好用。dataTables有很多的功能,具体可以查看官网 | 中文官网。

在这里我讲一下我在项目中使用到的功能。

基础入门

dataTables 入门教程笔记

1.常见的参数讲解

  • autoWidth - 自动计算列宽

这个值默认是true的,所以我们不用去设置它

  • serverSide - 开启服务器模式
  • ajax.data - 请求参数
  • ajax.dataSrc - 相当于jQuery的ajax的success
  • ajax - 请求url
  • data - 直接指定数据
  • destroy - 销毁表格对象
  • retrieve - 检索实例,检索当前存在的dt实例,继续使用它
  • columns.data - 指定数据源属性
  • columns.render - 渲染函数

data:当前数据, type:。。。, row:当前行,整行数据,可以使用点语法来获取数据 meta

  • columns.visible - 设置列显示或隐藏
  • columnsDefs - 设置列的属性
  • dom - 表格定位

2.常用的回调方法和api

  • initComplete - 初始化完毕
  • footerCallback - tfoot回调函数
  • dt.ajax.reload() - 重新加载数据

dt指的是用datatables实例化后返回的对象,如果是用dataTables实例化,调用时应该带上api(),如table.api().ajax.reload(),如果是用DataTable实例化,则不用带上api(),如table.ajax.reload()

  • dt.ajax.url().load() - 更换url并加载数据

url中可以带参数,即数据源链接
当url不带参数时,dt.ajax.url().load() == dt.ajax.reload()

  • dt.ajax.url() - 更换url
  • dt.draw() - 重绘
  • $.fn.dataTable.util.throttle() - 减少方法执行次数,比如我在搜索的时候,我不想每次键入一个单词就搜索一次,我可以用这个函数来控制搜索延迟,可以是3s后搜索一次等

3.服务器模式

请求参数

  • draw - 请求次数,即表示的是第几次请求
  • start - 起始位置,即分页起始位置
  • length - 长度,即分页长度
  • search[value] - 搜索框里的值
  • order[i][column] - 那一列排序
  • order[i][dir] - 排序方式
  • columns[i][data] - 列的属性名
  • columns[i][name] - 列的名字 需要配置 columns.name
  • columns[i][searchable] - 是否能被搜索
  • columns[i][orderable] - 是否排序
  • columns[i][search][value]

返回参数

  • draw - 请求次数
  • recordsTotal - 总条数
  • recordsFiltered
  • data - 返回的数据
  • error

自定义dom

参考:DOM定位 基本初始化 示例 Datatables中文网 | option dom 自定义布局表格

datatables默认会打开部分特性,比如搜索框,分页显示等等,或许你不喜欢datatables这样去布局,可能你想把分页按钮放在底部的中间,搜索框放在顶部的左上角,不用担心datatables考虑到这个问题,使用dom选项就可以灵活配置各个特性的位置。

datatables定义了10个字符表示不同的组件

  • l - Length changing 每页显示多少条数据选项
  • f - Filtering input 搜索框
  • t - The Table 表格
  • i - Information 表格信息
  • p - Pagination 分页按钮
  • r - pRocessing 加载等待显示信息
  • < and > - div elements 一个div元素
  • <”#id” and > - div with an id 指定id的div元素
  • <”class” and > - div with a class 指定样式名的div元素
  • <”#id.class” and > - div with an id and class 指定id和样式的div元素

我可以先放置一个占位的class,然后在表格实例化完成之后,再去动态添加元素,以此来实现高度可定制的dom。如:

dom: '<"dataTable-top table-toolBar"><"table-body"rt><"dataTable-bottom"lip><"clear">',// 添加自定义dom$('div.dataTable-top').html(searchBox + '<div class="clearfix">' + dataTableSearch + dataTableToolBar + '</div>');

服务器模式

参考:自行封装请求和返回数据的零耦合服务端分页 网友共享 示例 Datatables中文网

Datatables有许多方法来获取你的数据,如果你的数据量比较大,这个时候你需要使用服务器模式来处理你的数据。 在服务器模式下,所有的分页,搜索,排序等操作,Datatables都会交给服务器去处理。所以每次绘制Datatables, 都会请求一次服务器获取需要的数据。

通过配置serverSide这个属性来打开Datatables的服务器模式

serverSide: true,processing: true, // 服务器加载数据等待提示

此时使用ajax来获取数据

"ajax": "../resources/server_processing_custom.php"

当然你也可以自定义ajax,比如我的项目中

ajax : function(data, callback, settings) {//ajax配置为function,手动调用异步查询    console.log(data, callback, settings);    //手动控制遮罩    // $wrapper.spinModal();    //封装请求参数    var param = _this.getQueryCondition(data);    $.ajax({        type: "GET",        url: "/api/employee",        cache : false,  //禁用缓存        data: param,    //传入已封装的参数        dataType: "json",        success: function(result) {            //异常判断与处理            if (result.errorCode) {                // $.dialog.alert("查询失败。错误码:"+result.errorCode);                return;            }            //封装返回数据,这里仅演示了修改属性名            var returnData = {};            returnData.draw = data.draw;//这里直接自行返回了draw计数器,应该由后台返回            returnData.recordsTotal = result.total;            returnData.recordsFiltered = result.total;//后台不实现过滤功能,每次查询均视作全部结果            returnData.data = result.pageData;            //关闭遮罩            // $wrapper.spinModal(false);            //调用DataTables提供的callback方法,代表数据已封装完成并传回DataTables进行渲染            //此时的数据需确保正确无误,异常判断应在执行此回调前自行处理完毕            console.log('success', returnData);            callback(returnData);        },        error: function(XMLHttpRequest, textStatus, errorThrown) {            $.dialog.alert("查询失败");            $wrapper.spinModal(false);        }    });},

添加序号和复选框

参考:给表格添加索引(Type selector-modifier 应用) | option columns.render 渲染列(1) 添加checkbox

首先必须定义好相关的列,添加复选框,使用render来渲染单元格dom元素

columns: [    { //复选框单元格        className: "td-checkbox",        "searchable": false,        "orderable": false,        // width: "30px",        data: null,        render: function (data, type, row, meta) {            return '<input type="checkbox" class="flat">';        }    },    {        data: null    },    {data: 'firstName'},    {data: 'lastName'},    {data: 'position'},    {data: 'office'},    {data: 'age'},    {data: 'startDate'},    {data: 'salary'},    {data: 'extn'},    {data: 'email'}]

添加序号不能像复选框那样,而应该在表格生成完之后,再去渲染

'fnDrawCallback': function () {    _this.table.column(1, {        search: 'applied',        order: 'applied'    }).nodes().each(function(cell, i) {        //i 从0开始,所以这里先加1        i = i+1;        //服务器模式下获取分页信息,使用 DT 提供的 API 直接获取分页信息        var page = _this.table.page.info();        //当前第几页,从0开始        var pageno = page.page;        //每页数据        var length = page.length;        //行号等于 页数*每页数据长度+行号        var columnIndex = (i+pageno*length);        cell.innerHTML = columnIndex;    });},

自定义搜索,服务器排序,分页

参考:自行封装请求和返回数据的零耦合服务端分页 网友共享 示例 Datatables中文网

在服务器模式下,通过改变传递到服务器的参数,来实现自定义搜索,排序和分页

getQueryCondition : function(data) {    var param = {};    //组装排序参数    if (data.order&&data.order.length&&data.order[0]) {        switch (data.order[0].column) {            case 2:                param.orderColumn = "firstName";                break;            case 3:                param.orderColumn = "lastName";                break;            case 4:                param.orderColumn = "position";                break;            case 5:                param.orderColumn = "office";                break;            case 6:                param.orderColumn = "age";                break;            case 7:                param.orderColumn = "startDate";                break;            case 8:                param.orderColumn = "salary";                break;            case 9:                param.orderColumn = "extn";                break;            case 10:                param.orderColumn = "email";                break;            default:                param.orderColumn = "firstName";                break;        }        param.orderDir = data.order[0].dir;    }    //组装查询参数    param.fuzzySearch = this.fuzzySearch;    if (param.fuzzySearch) {        param.fuzzy = (!this.searching && this.localState !== null) ? this.localState.search.search : $("#tableSearch").val();    }else{        param.firstName = (!this.searching && this.localState !== null) ? this.localState.search.field.firstName : $("#firstName-search").val();        param.lastName = (!this.searching && this.localState !== null) ? this.localState.search.field.lastName : $("#lastName-search").val();        param.position = (!this.searching && this.localState !== null) ? this.localState.search.field.position : $("#position-search").val();        param.office = (!this.searching && this.localState !== null) ? this.localState.search.field.office : $("#office-search").val();        param.age = (!this.searching && this.localState !== null) ? this.localState.search.field.age : $("#age-search").val();        param.startDate = (!this.searching && this.localState !== null) ? this.localState.search.field.startDate : $("#startDate-search").val();        param.salary = (!this.searching && this.localState !== null) ? this.localState.search.field.salary : $("#salary-search").val();        param.extn = (!this.searching && this.localState !== null) ? this.localState.search.field.extn : $("#extn-search").val();        param.email = (!this.searching && this.localState !== null) ? this.localState.search.field.email : $("#email-search").val();    }    //组装分页参数    param.startIndex = data.start;    param.pageSize = data.length;    param.draw = data.draw;    console.log(param);    return param;}

记忆功能,保存状态

参考:关于 DataTables 本地储存那点事,又爱又恨 (stateSave参数应用)

//开启本地保存功能stateSave: true,    //保存状态操作    "stateSaveParams": function (settings, data) {    console.log("stateSaveParams", data, JSON.parse(localStorage.getItem('DataTables_' + settings.sInstance)));    //这里可以操作保存的数据,写上自己特定的逻辑    data.search.search = $("#tableSearch").val();    data.search.fuzzySearch = _this.fuzzySearch;    data.search.field = {        firstName: $("#firstName-search").val(),        lastName: $("#lastName-search").val(),        position: $("#position-search").val(),        office: $("#office-search").val(),        age: $("#age-search").val(),        startDate: $("#startDate-search").val(),        salary: $("#salary-search").val(),        extn: $("#extn-search").val(),        email: $("#email-search").val()    }},"stateSaveCallback": function (settings, data) {    console.log("stateSaveCallback", data);    //DT默认保存的key值为DataTables_+表格id+页面名称    localStorage.setItem('DataTables_' + settings.sInstance, JSON.stringify(data));},//读取状态操作"stateLoadParams": function (settings, data) {    console.log("stateLoadParams", data);    //在读取数据的时候可以改变数据,根据自己逻辑来处理    //data.search.search = "";    //或者你可以直接禁用从缓存里读取数据,只要直接返回false即可    //return false;},"stateLoadCallback": function (settings) {    console.log("stateLoadCallback", JSON.parse(localStorage.getItem('DataTables_' + settings.sInstance)));    return JSON.parse(localStorage.getItem('DataTables_' + settings.sInstance));},//状态加载完后执行的回调函数"stateLoaded": function (settings, data) {    console.log("stateLoaded", data);    //在这里你可以打印出保存的缓存数据    //alert( 'Saved filter was: '+data.search.search );},

其它功能

rowId: '_id', // 为每一行数据添加上id,此处的_id是从服务器获取的// 多语言language: {    "lengthMenu": "每页 _MENU_ 条记录",        "zeroRecords": "没有找到记录",        "info": "第 _PAGE_ 页 ( 总共 _PAGES_ 页 )",        "infoEmpty": "无记录",        "infoFiltered": "(从 _MAX_ 条记录过滤)",        "paginate": {        "first": "<<",            "previous": "<",            "next": ">",            "last": ">>"    },    "search": "模糊查询:"},paginationType: 'full_numbers', // 分页功能"order": [[2, 'asc']], // 默认排序initComplete: ... // 初始化完成fnDrawCallback: ... // 渲染表格完成回调

我在项目中遇到的问题

参考:JQuery Datatable Ajax请求两次问题的解决

  1. 由于在服务器模式下,设置scrollX为true,顶部thead会有bug,所以不设置这个属性
  2. draw()方法会重新从服务器拉取数据,以下代码会导致ajax两次,所以我将添加行号放在了’fnDrawCallback’回调函数中
table = $('#aaa').DataTable({...});// 初始化完成,添加行号    table.on('order.dt search.dt',function() {        table.column(1, {            search: 'applied',            order: 'applied'        }).nodes().each(function(cell, i) {            cell.innerHTML = i + 1;        });    }).draw();