您的位置:首页 > Web前端 > JQuery

使用jquery.datatable.js遇到的一些坑

2017-07-31 19:24 211 查看
写在最前面的话,如果不是维护老项目或者在老项目上二次开发尽量不要用这个表格插件

为什么呢?

1.老项目基本用的是1.09及之前的版本;这个插件1.09和1.10之后的版本命名及加载方式,完全改变了;1.09版本的API

基本没有英文的我是没找到,中文呢基本靠博客中的只言片语,但这些博客很多是有错误的,包括我自己写的可能都是有些方法没理解透造成的问题,

不过这个插件真的不好用
http://datatables.club/upgrade/1.10-convert.html  1.09和1.10的一些对比

2.这个插件的sdom参数有人说强大,但是我觉得这个参数对于UI优化简直是个大坑

3.一个写的比较全的的API博客

参数配置:http://blog.csdn.net/zhu_xiao_yuan/article/details/51252300

回调函数:http://www.cnblogs.com/zhangwei595806165/p/3701463.html

列举遇到的一些问题及解决办法

1.所有页面表格的公共初始化方法:1.10有个default方法,1.09之前是木有的;但是又不想重复js代码维护起来也麻烦,有俩种方式一、
  反压缩jQuery.datatable.js在2050行左右修改代码如下:浅红色的是我修改的一些公共初始化

j.defaults = {
sPaginationType: "bootstrap",
bLengthChange: true,
bPaginate: true,
iDisplayStart: 0,
iDisplayLength: 10,
aLengthMenu: [10, 20, 50],
bAutoWidth: false,
bFilter: false,
bDestroy:true,
bProcessing: true,
bRetrieve: true,
bServerSide: true,
bSort: false,
iCookieDuration: 60 * 60 * 24 * 7,
oLanguage: {
sInfo: "当前第 _START_ - _END_ 条 共计 _TOTAL_ 条",
sInfoEmpty: "当前第 0 - 0条 共计 0 条",
sInfoFiltered: "(从 _MAX_ 条记录中过滤)",
sLengthMenu: "每页显示 _MENU_条",
sLoadingRecords: "加载中...",
sProcessing: "加载中...",
sSearch: "搜索:",
sZeroRecords: "没有找到符合条件的数据",
sEmptyTable: "没有找到符合条件的数据",
oPaginate: {
sFirst: "首页",
sLast: "尾页",
sNext: "下一页",
sPrevious: "上一页"
},
oAria: {
sSortAscending: ": activate to sort column ascending",
sSortDescending: ": activate to sort column descending"
},
sInfoPostFix: "",
sInfoThousands: ",",
sUrl: "",

},
aoColumnDefs: [{
sDefaultContent: '',
aTargets: ['_all']
}],

};

二、在公共js中对表格都加载一次

这种方式有点不好就是当我不需要展现表格的时候它也请求了一次后台;span12-pag{width:96%}是自己写的一个样式,插件的分页条长度超过了表格宽度

$(".datatable").datatable({

"sScrollY": 474, // DataTables的高

"sDom": "<'box-content'<'span12'l>tr<'span12 span12-pag'p>>",

})

2.1.09版本没有提供一个异步加载的方法,以下自己封装的一个

// 异步刷新表格数据

$.fn.dataTableExt.oApi.fnReloadAjax = function(oSettings) {
this.fnClearTable(false);
this.oApi._fnProcessingDisplay(oSettings, true);
var that = this;

$.getJSON(oSettings.sAjaxSource, null, function(json) {
if(json.aaData!=null) {
for(var i = 0; i < json.aaData.length; i++) {
that.oApi._fnAddData(oSettings, json.aaData[i]);
}
oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
that.fnDraw();
that.oApi._fnProcessingDisplay(oSettings, false);
}

});

}

3.自己封装的分页方法,插件提供的俩中默认方式不符合要求

// 分页方法 bootstrap 形式

$.extend($.fn.dataTableExt.oPagination, {
"bootstrap": {
"fnInit": function(oSettings, nPaging, fnDraw) {
var oLang = oSettings.oLanguage.oPaginate;
var fnClickHandler = function(e) {
e.preventDefault();
if(oSettings.oApi._fnPageChange(oSettings,e.data.action)) {
fnDraw(oSettings);
}
};

$(nPaging).addClass('pagination')
.append('<ul>' +'<li class="prev disabled"><a href="#">← ' +
oLang.sPrevious +'</a></li>' +'<li class="next disabled"><a href="#">' +
oLang.sNext +' → </a></li>' +'</ul>');
var els = $('a', nPaging);
$(els[0]).bind('click.DT', {
action: "previous"
}, fnClickHandler);
$(els[1]).bind('click.DT', {
action: "next"
}, fnClickHandler);
},

"fnUpdate": function(oSettings, fnDraw) {
var iListLength = 5;
var oPaging = oSettings.oInstance.fnPagingInfo();
var an = oSettings.aanFeatures.p;
var i, j, sClass, iStart, iEnd, iHalf = Math
.floor(iListLength / 2);

if(oPaging.iTotalPages < iListLength) {
iStart = 1;
iEnd = oPaging.iTotalPages;
} else if(oPaging.iPage <= iHalf) {
iStart = 1;
iEnd = iListLength;
} else if(oPaging.iPage >= (oPaging.iTotalPages - iHalf)) {
iStart = oPaging.iTotalPages - iListLength + 1;
iEnd = oPaging.iTotalPages;
} else {
iStart = oPaging.iPage - iHalf + 1;
iEnd = iStart + iListLength - 1;
}

for(i = 0, iLen = an.length; i < iLen; i++) {
// remove the middle elements
$('li:gt(0)', an[i]).filter(':not(:last)').remove();
// add the new list items and their event
// handlers
for(j = iStart; j <= iEnd; j++) {
sClass = (j == oPaging.iPage + 1) ? 'class="active"' :'';
$('<li ' + sClass + '><a href="#">' +j + '</a></li>')
.insertBefore($('li:last', an[i])[0])
.bind('click',function(e) {
e.preventDefault();
oSettings._iDisplayStart = (parseInt($('a', this).text(),10) - 1) *oPaging.iLength;
// 这里将分页参数传递至表格初始化中重绘表格,重新load数据
fnDraw(oSettings);
});
}

// add / remove disabled classes from the static
// elements
if(oPaging.iPage === 0) {
$('li:first', an[i]).addClass('disabled');
} else {
$('li:first', an[i])
.removeClass('disabled');
}

if(oPaging.iPage === oPaging.iTotalPages - 1 ||
oPaging.iTotalPages === 0) {
$('li:last', an[i]).addClass('disabled');
} else {
$('li:last', an[i]).removeClass('disabled');
}
}
}
}

4.当有tab标签页的页面并且有多个表格时,切换tab标签数据展示不是默认第一页:

我是reload表格后,用jquery模拟了一个a标签点击事件,选择器对不同表格可能要略做修改

$(".dataTables_paginate").find("ul").eq(1).children("li").children("a").eq(1).click();

5.bvisible参数,使用该参数需要在需隐藏的列上加上"bvisible":false,通过fnSetColumnVis来控制列的显隐,但是我发现每次调用都请求了一次后台;

有种取巧方式:是将后台数据封装成一个统一的对象名返回,通过选择器修改表头的列名

6.后台返回分页数据

function initTable(urlRwrite) {
objTable = $("#resourceTable").dataTable({
"sScrollY": 530, // DataTables的高
'bFilter': true, // 是否使用内置的过滤功能
"sDom": "<'box-content'<'span6'f><'span6'l>tr<'span12 span12-pag'p>>",
"oLanguage": { // 汉化
"sSearch": "资源名称/URL:",
},
"sAjaxSource":urlRwrite==undefined? "/shore/admin/role/listResource.ajax?projectId=0&T=" 

+ new Date().getTime():urlRwrite,
"aoColumns": [{
"fnCreatedCell": function(nTd, sData, oData, iRow, iCol) {
var resourceId = oData.fResourceId;
var str = "<input type='checkbox'  name='resourceId'  id='resourceId-" + resourceId 

+ "'  onclick='changeId(this," + resourceId + ")'/>";
$(nTd).html(str);
},
"sWidth": "6%"
}, {
"mDataProp": "fResourceName",
"sWidth": "14%"
}, {
"mDataProp": "fResourceUrl",
"sWidth": "24%"
}, {
"mDataProp": "fLastUpdatedBy",
"sWidth": "18%"
}, {
"mDataProp": "fLastUpdatedTime",
"sWidth": "15%"
}, {
"fnCreatedCell": function(nTd, sData, oData, iRow, iCol) {
var resourceId = oData.fResourceId;
var str = "";
if(projectType == 1) {
str += "<button class='btn btn-success button-margin-right editBtn' type='button' 

onclick='editProperty(" + resourceId + ")' disabled='true' 

title='资源必须和角色绑定后才能进行此操作' id='btn1-" + resourceId + "'> 

<i class='icon-edit icon-white'></i>编辑属性</button>";
str += "<button class='btn btn-success button-margin-right delBtn btn-top' type='button' 

onclick='editResourceRoleOu(" + resourceId + ")' disabled='true' 

title='资源必须和角色绑定后才能进行此操作' id='btn2-" + resourceId + "'> 

<i class='icon-edit icon-white'></i>编辑访问权限</button>";
}else{
str += "<button class='btn btn-success button-margin-right btnBtn' type='button' 

onclick='loadBtnAuth(" + resourceId + ")'  id='btn3-" + resourceId
+ "' disabled='true'> 

<i class='icon-edit icon-white'></i>按钮授权</button>";
}

$(nTd).html(str);
},

}],
"fnServerData": function(sSource, aoData, fnCallback) {
var iDisplayStart = 0;
var iDisplayLength = 10;
var sSearch = '';
$.each(aoData, function(i, o) {
if(o.name == "iDisplayStart") {
iDisplayStart = o.value;
}
if(o.name == "iDisplayLength") {
iDisplayLength = o.value;
}
if(o.name == "sSearch") {
sSearch = o.value;
}
});
$.ajax({
"type": 'get',
"url": sSource,
"dataType": "json",
"data": {
iDisplayStart: iDisplayStart,
iDisplayLength: iDisplayLength,
sSearch: sSearch
},
"success": function(resp) {
fnCallback(resp);
},
"complete": function(XMLHttpRequest,
textStatus) {
var data = XMLHttpRequest.responseText;
if(data == "timeout") {
window.location = "/";
}
}
});
},
"fnDrawCallback": function() { // 复选框反选操作
$.each(checkedResourceIds, function(i, o) {
if(deleteResourceIds.indexOf(o) == -1) {
$("#resourceId-" + o).prop("checked", true);
$("#btn1-" + o).attr("disabled", false);
$("#btn2-" + o).attr("disabled", false);
$("#btn3-" + o).attr("disabled", false);
$("#btn1-" + o).attr("title", "");
$("#btn2-" + o).attr("title", "");
} else {
$("#resourceId-" + o).prop("checked", false);
}
});
$.each(addResourceIds, function(i, o) {
$("#resourceId-" + o).prop("checked", true);
$("#btn1-" + o).attr("disabled", false);
$("#btn2-" + o).attr("disabled", false);
$("#btn3-" + o).attr("disabled", false);
$("#btn1-" + o).attr("title", "");
$("#btn2-" + o).attr("title", "");
});
},
"fnRowCallback": function (nRow, aData, iDisplayIndex) {
$('td:eq(1)', nRow).html(escapeHtml(aData.fResourceName));

            $('td:eq(2)', nRow).html(escapeHtml(aData.fResourceUrl));

            $('td:eq(4)', nRow).html(aData.fLastUpdatedTime.substring(0,aData.fLastUpdatedTime.length-2));

        }
})

}

7.定义列框时只在表头定义width是无效的,必须在列中定义:"sWidth": "14%"

8.对表格数据的字符转码和数据格式化可以在fnRowCallback中进行操作

9.对表格定义的复选框翻页无法选中问题可在fnDrawCallback对表格进行操作

10.当表格的异步参数改变时必须修改url否则无法将新的参数传递至后台

11.不知道为啥使用fnClearTable(false)方法并没有清楚数据,我使用了中取巧方式$("tbody").empty("");
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: