工欲善其事,必先利其器
本系列文章介紹我在運維系統開發過程中用到的那些順手的前端插件,上一篇文章介紹了Datatables插件的基本使用,這一篇文章作為上一篇的延續,會介紹Databases的一些高級用法,例如從不同的數據源獲取數據、修改數據最終呈現方式、操作Dom改變頁面功能、開啟服務端數據處理等
數據加載
上篇文章中的所有數據都是直接渲染的html中的table數據,datatables還支持其他幾種數據源,以方便實現更靈活的控制
從數組中獲取
<table id="myTable-x" class="display" style="width:100%"></table>
$(document).ready(function() {
var dataSet = [
["3","https://ops-coffee.cn","2018-07-03"],
["9","https://demo.ops-coffee.cn", "2019-08-06"],
];
$('#myTable-x').DataTable({
"data": dataSet,
"columns": [
{ title: "Id" },
{ title: "Site" },
{ title: "Date" },
]
})
});
data: 指定數組
columns: 配置每一列的title
注意:從數組中獲取數據一定要有表頭,如果沒有則可能會報下邊的錯:
Uncaught TypeError: Cannot read property 'aDataSort' of undefined
解決方法就是datatables添加columns
配置,或者寫上table的thead
<table id="myTable-x" class="display" style="width:100%">
<thead>
<tr>
<th>ID</th>
<th>Site</th>
<th>Date</th>
</tr>
</thead>
</table>
從對象中獲取
<table id="myTable-x" class="display" style="width:100%"></table>
$(document).ready(function() {
var dataSet = [
{"Id":"3","Site":"https://ops-coffee.cn","Date":"2018-07-03"},
{"Id":"9","Site":"https://demo.ops-coffee.cn","Date":"2019-08-06"},
];
$('#myTable-x').DataTable({
"data": dataSet,
"columns": [
{"data": "Id", "title": "Id"},
{"data": "Site", "title": "Site"},
{"data": "Date", "title": "Date"},
]
})
});
使用對象數組,一定要配置columns的data
,告訴DataTables每列對應的屬性,title
配置可選,添加title會給表格添加表頭
從實例中獲取
$(document).ready(function() {
function dataSet(id, site, date) {
this.id = id;
this.site = site;
this.date = date;
};
$('#myTable-x').dataTable({
data: [
new dataSet("3", "https://ops-coffee.cn", "2018-07-03"),
new dataSet("9", "https://demo.ops-coffee.cn", "2019-08-06"),
],
columns: [
{"data": "id", "title":"Id"},
{"data": "site", "title":"Site"},
{"data": "date", "title":"Date"}
]
});
});
Ajax異步獲取
Datatables還支持Ajax的方式異步加載數據,簡單的方式是直接配置一個url地址即可
$(document).ready(function() {
$('#myTable-x').dataTable({
"ajax": 'sdata.json'
});
});
ajax接收的數據可以是數組或者對象,注意columns
的配置,可以對應參考前文兩種格式數據的處理
結果數據處理
上邊的table可以發現有個site列的內容是一個網址,如果我們想讓網址能夠點擊該如何實現呢?可以利用columns
的render
屬性對展示結果進行更改
$(document).ready(function() {
$('#myTable-x').dataTable({
"ajax": 'sdata.json',
"columns": [
{"data": "id", "title":"Id"},
{
"data": "site",
"title":"Site",
"render": function (data, type, row) {
return '<a href='+data+' target="_blank">'+data+'</a>'
}
},
{"data": "date", "title":"Date"}
]
});
});
render后邊跟了個函數,每當數據表需要獲取列中某個單元格的數據時render
函數都會執行,且函數可能會被執行多次,函數默認接收三個參數,意思分別是:
data: 單元格的具體數據,例如https://ops-coffee.cn
type: 標識了這一次調用的請求類型,會有filter
、display
、type
、sort
row: 這一行的完整數據源,如果像Demo示例傳了對象數據,那么可以通過row.site
獲取到這一行site列的數據
拿到參數進行一系列的處理后可以通過return
返回最終想要展示的內容
當然也可以通過columns
在表格末尾添加一列以實現編輯、刪除的按鈕展示
"columns": [
{"data": "id", "title":"Id"},
{
"data": "site",
"title":"Site",
"render": function (data, type, row) {
return '<a href='+data+' target="_blank">'+data+'</a>'
}
},
{"data": "date", "title":"Date"},
{
"data": "id",
"title": "操作",
"render": function (data, type, row) {
return '<a href="#update/'+row.id+'/" class="btn btn-warning btn-sm">編輯</a> ' +
'<a href="#delete/'+row.id+'/" class="btn btn-danger btn-sm">刪除</a>'
}
}
]
最終呈現結果如下圖
Dom操作
如果我不需要datatables顯示左上角的每頁顯示條數信息,而要換成一個添加按鈕改怎么做呢?這里可以借助datatables的dom來實現
默認情況下表格都會有左上角的每頁顯示條數、右上角的搜索、左下角的表格信息、右下角的分頁、中間的數據加載等待以及表格本身,這些都是datatables的DOM,它們實際上就是一個div包裹起來的select、input之類的html標簽,datatables中的每個DOM都與一個字母相對應,他們的對應關系如下:
l: length,代表左上角的每頁顯示條數控件
f: filtering,代表右上角的搜索控件
t: table,代表表格本身
i: information,代表左下角的表格信息控件
p: pagination,代表右下角的分頁控件
r: processing,代表中間數據加載等待提示控件
這些控件在datatables里可以通過配置dom
來控制他們的顯示位置,以及是否顯示,默認的顯示順序是lfrtip
$('#myTable-x').dataTable({
"dom": 'lfrtip'
})
你如果不想顯示某個控件,可以通過去掉dom
配置項里對應的字母實現,同時Datatables支持四個自定義的標簽,通過這四個標簽可以方便的來修改DOM的展示
< >
尖括號就代表html里的div
<"class">
代表了添加了class的div
<"#id">
代表了添加了id的div
<"#id.class">
代表添加了id和class的div
我們想把右上角的每頁顯示條數控件換成添加按鈕的話可以這樣寫
$('#myTable-x').dataTable({
"dom": '<"#add-btn.toolbar">frtip'
})
$("#add-btn.toolbar").html(
'<button href="#add" class="btn btn-success btn-sm"> + 添加</button>'
)
遇到樣式問題,需要添加css
<style type="text/css">
.toolbar {float:left}
</style>
這樣就完美實現了
服務器端處理
Datatables支持使用服務端進行數據處理,當開啟服務端數據處理后,Datatables將在頁面執行分頁、排序、搜索等操作時向服務端發出Ajax請求,Ajax請求會傳遞許多變量給服務端,服務端接收到請求后根據變量的值對數據進行處理,處理完成按照固定的格式返回給前端頁面,頁面對返回的數據進行渲染提供給用戶查看
開啟服務器模式只需要兩個設置項serverSide
和ajax
$('#myTable-x').dataTable({
"serverSide": true,
"processing": true,
"ajax": '/api/site/data'
})
serverSide: 為true時表示開啟服務端處理模式
processing: 為true時會開啟數據處理中的提示,非必須
ajax: 指定服務器端的地址,可以像上邊一樣是個字符串,也可以像jQuery.ajax一樣作為一個對象使用,例如我想傳遞額外的參數(datatables默認會給后端傳遞許多的參數,下邊有講)給后端服務器的話,可以這樣用
$('#myTable-x').dataTable({
"serverSide": true,
"processing": true,
"ajax": {
"url": "/api/site/data",
"data": function (d) {
d.type = 'ops-coffee';
}
}
})
data: 可以在發送請求給后端時額外增加type=ops-coffee
的參數
發送到服務器端的參數
當開啟服務端數據處理后,默認會給服務端傳遞許多參數,大概如下:
draw:繪制計數器,主要用來確保Ajax從服務器端接收到的數據是對應同一次請求的
start:第一條數據的起始位置
length:每頁顯示的條數
search[value]:全局的檢索關鍵字
order[i][column]:告訴服務器哪些列是需要排序的,i為排序列的序號,下邊的i相同含義,注意i是從0開始的
order[i][dir]:告訴服務器排序的方式"desc","asc"
columns[i][data]:columns上定義的data屬性值
columns[i][name]:columns上定義的name屬性值
columns[i][searchable]:告訴服務器哪些列可以被搜索
columns[i][orderable]:告訴服務器哪些列可以進行排序
columns[i][search][value]:告訴服務器某些列的具體搜索條件
如果需要后台分頁,那么需要拿到start
、length
兩個參數做相應的處理,
如果有搜索的內容,那么需要拿到serch[value]
參數做處理
服務端返回數據的格式
服務端需要返回datatables可以處理的數據格式,具體數據格式如下:
{
"draw": 1,
"recordsTotal": 7,
"recordsFiltered": 7,
"data": [
{
"id": 3,
"site": "https://ops-coffee.cn",
"date": "2018-07-03"
},
{
"id": 9,
"site": "https://demo.ops-coffee.cn",
"date": "2019-08-06"
}
// 省略其他結果
]
}
draw: 客戶端調用服務端次數標識,客戶端傳過來是什么原樣返回回去即可,無需修改
recordsTotal: 數據總條數,沒有過濾的數據總條數
recordsFiltered: 過濾后符合要求的條數,如果沒有搜索參數那么這個值與recordsTotal
一致
data: 需要顯示的具體數據,json格式
API調用
Datatables提供了強大的API來處理表格上的數據,可以通過API添加數據到已經存在的表格,或者對已經存在的數據進行操作,API的類型非常豐富,詳細的信息可以查閱官網,使用方法如下:
跳轉到頁
跳轉到第3頁:
var table = $('#myTable').DataTable()
table.page(2).draw(false)
page(2): page為分頁方法,后邊的2表示跳轉到第幾頁,可以是一個數字,也可以是first
、next
、previous
、last
這樣的字符串,當為數字時要從0算起,例如示例中為2實際上是跳轉到了第3頁
draw(false): 對表格進行重繪以實現表格更新的顯示,大多數的api操作都不會直接更新在頁面上,所以需要調用下draw
,默認情況下重繪后分頁會被重置回到第一頁,當設置為false
時分頁不會被重置
搜索某列
搜索第2列包含https://ops-coffee.cn
的行
var tablx = $('#myTable').dataTable()
tablx.api().column(1).search('https://ops-coffee.cn').draw()
首先需要注意這個例子中的API調用使用了.api()
,這是因為上一個例子在初始化時用了.DataTable()
而這個例子初始化時用了.dataTable()
,僅僅是d字母大小寫的區別而已,但意義確不同,前者直接返回API實例,后者返回的是jQuery實例
完整Demo
為了方便大家學習,我寫了個完整的demo,你可以在線查看效果或下載代碼應用到自己的項目中
在線Demo地址:https://demo.ops-coffee.cn/datatables/
Github源碼地址:https://github.com/ops-coffee/demo/tree/master/datatables
相關文章推薦閱讀: