前言
Datatables是一款jquery表格插件。它是一個高度靈活的工具,可以將任何HTML表格添加高級的交互功能。
DataTables中文網
DataTables英文網(資料更多)
IT狗窩
Editor
Editor是官方提供的表格編輯寬展組件。
優點:一大堆;
缺點:付費,破解版一般是老版本
今天主角不是官方的組件,所以跳過。
DataTables.AltEditor(免費,開源)
DataTables最低兼容版本1.10.8
提供簡單的添加、編輯和刪除Buttons,只需要簡單的設置即可:
var availableButtons = [
{text: '添加', name: 'add'},
{extend: 'selected', text: '編輯', name: 'edit'},
{extend: 'selected', text: '刪除', name: 'delete'}
];
$(tableId).dataTable({
columnDefs: columnHeader,
data: data.data,
altEditor: true, // 必須設置為true
dom: "Bfrtip",
buttons: availableButtons,
onAddRow: function (datatable, rowdata, success, error) {
//點擊添加Button觸發事件
},
onDeleteRow: function (datatable, rowdata, success, error) {
/點擊刪除Button觸發事件
},
onEditRow: function (datatable, rowdata, success, error) {
//點擊編輯Button觸發事件
}
})
Bug分析
原作者的AltEditor寫的很好了(愛動手造輪子的都是好孩子),在一個DataTable情況下,沒發現Bug,如果是初始化了多個DataTable,其中任意一個DataTable點擊添加(編輯或刪除),所有DataTable都會觸發onAddRow(onEditRow或onDeleteRow),這點我開始沒注意,后來才發現的。
這個Bug可是夠大了,于是開始各種找,最后花了兩天各種調試才找到。
首先點擊添加(編輯或刪除)都會彈出窗口(div),但是,每個DataTable彈出的窗口中button都相同,做事件綁定時就會把所有相同id的button綁定上這個事件。也就是說,初始化DataTable很多,一次觸發次數也會很多。
繼續找問題
以一段代碼為例
$('#altEditor-modal').on('show.bs.modal', function () {
var btns = '<button type="button" data-content="remove" class="btn btn-default" data-dismiss="modal">關閉</button>' +
'<button type="button" data-content="remove" class="btn btn-primary" id="editRowBtn" >提交更改</button>';
$('#altEditor-modal').find('.modal-title').html('編輯記錄');
$('#altEditor-modal').find('.modal-body').html(data);
$('#altEditor-modal').find('.modal-footer').html(btns);
});
id="editRowBtn" 這個東西萬年不變。源代碼那些操作提交按鈕都是寫死的ID。
動手解決
好了,問題就是id重復了,那怎么辦?在AltEditor庫中為了區分不同DataTable,有一個叫做 namespace 的屬性,一個叫做 _instance 每綁定一個DataTable就會有一個全局變量自加1,namespace 就是字符串 “.altEditor"+_instance。
var _instance = 0;
var altEditor = function (dt, opts) {
//省略一萬字
this.s = {
dt: new DataTable.Api(dt),
namespace: '.altEditor' + (_instance++)
};
//省略一萬字
}
這樣能保證他知道哪個是當前操作的DataTable。
我們把id="editRowBtn"變成id="editRowBtn"+namespace,這樣就保證唯一性了。
在不同的方法內找到namespace的變量不太一樣, this.s.namespace或者 that.s.namespace。
替換所有需要id的地方十幾處。
大功告成?
namespace:".altEditor"+_instance,這個有問題,namespace字符串雖然拼在了id后面,但是因為包含一個點,導致提交事件不觸發,所以最后應該是namespace:“altEditor"+_instance就行了。
部分改造代碼
var btns = '<button type="button" data-content="remove" class="btn btn-default" data-dismiss="modal">關閉</button>' +
'<button type="button" data-content="remove" class="btn btn-primary" id="editRowBtn' + that.s.namespace + '" >提交更改</button>';
_editRowCallback: function (response, status, more) {
$("div#altEditor-modal").find("button#editRowBtn" + this.s.namespace).prop('disabled', true);
}
小期待
以下項目都是我圍繞遠程控制寫的項目和子項目。都給star一遍吧。??
項目(Github) | 語言 | 其他地址 | 運行環境 | 項目說明 |
---|---|---|---|---|
RemoteDataControllerForWeb | JavaScript | 簡書 | 瀏覽器 | 遠程數據調試控制臺Web端 |
RemoteDataControllerForAndroid | Java | 簡書 | Android設備 | 遠程數據調試Android端 |
RemoteDataControllerForServer | Java | 簡書 | 運行Java的設備 | 遠程數據調試Server端 |
MiniHttpClient | Java | 簡書 | 運行Java的設備 | 精簡的HttpClient |
MiniHttpServer | Java | 簡書 | 運行Java的設備 | 支持部分Http協議的Server |
MiniTCPClient | Java | 簡書 | 運行Java的設備 | TCP長連接庫,支持粘包拆包處理 |
PackageMessage | Java | 簡書 | 運行Java的設備 | TCP粘包與半包解決方案 |
ByteBuffer | Java | 簡書 | 運行Java的設備 | 二進制處理工具類 |
DataTables.AltEditor | JavaScript | 簡書 | 瀏覽器 | Web端表格編輯組件 |
我的小站:IT狗窩
技術聯系QQ:1264957104