GridManager 庫地址:http://gridmanager.lovejavascript.com/index.htmljavascript
本文旨在說明 GridManager 的使用技巧,若是想了解其配置使用,詳見文檔說明 https://gridmanager.lovejavascript.com/api/index.htmlhtml
export default class App extends Component { resource = () => fetch( "https://www.lovejavascript.com/learnLinkManager/getLearnLinkList" ).then((res) => res.json()); columnData = [ { key: "name", text: "名稱", align: "left" }, { key: "info", text: "使用說明" } ]; render() { return ( <div className="App"> <Table gridManagerName="test" disableLine supportAjaxPage checkboxConfig={{ useRowCheck: true }} supportDrag={false} supportCheckbox={false} ajaxData={this.resource} columnData={this.columnData} /> </div> ); }
完整代碼演示:https://codesandbox.io/s/optimistic-currying-1bxpj?file=/src/App.js前端
使用場景:須要純前端處理表格數據,這時候,咱們每每須要在前端實現分頁、排序、搜索和下載等函數的封裝。java
由於每次刷新表格的時候,都會調用 ajaxData 方法,這個方法會返回表格數據,所以,咱們只須要在 ajaxData 方法中調用上述封裝好的函數便可達到咱們要的效果。ajax
這種寫法很像過濾器,每個方法都是對原數據的一次過濾,最後返回過濾後的數據,下面是每一個方法的實現:json
原始數據originData後端
—filter—> searchData(originData): searchedDataapi
—filter—> sortingData(searchedData): sortedData數組
—filter—> paging(sortedData): pagedData瀏覽器
——>處理後的數據
ajaxData = async (settting, params) => { const originData = this.store.fetchData(); const searchedData = this.store.searchData(originData, this.state.keywords); const sortedData = this.store.sortingData(searchedData, params); this.csvData = sortedData.list; return await this.store.pagingData( sortedData, params.pageNum, params.pageSize ); };
pagingData(data, pageNum, pageSize) { const { list } = data; return Promise.resolve({ pageNum, pageSize, totals: list.length, list: list.slice((pageNum - 1) * pageSize, pageNum * pageSize) }); }
sortingData(data, query) { let sortProps = "DESC"; let sortOrder = ""; Object.keys(query).forEach((key) => { if (query[key] === "ASC" || query[key] === "DESC") { sortProps = key.split("_")[1]; sortOrder = query[key]; } }); const list = this.sort(data.list, sortProps, sortOrder); return { totals: list.length, list }; } sort(list, sortProps, sortOrder) { if (sortOrder === "ASC") { return sortBy(list, sortProps); } if (sortOrder === "DESC") { return sortBy(list, sortProps).reverse(); } return list; }
searchData(data, keywords) { const list = data.list.filter( (item) => item.name && item.name.indexOf(keywords) > -1 ); return { totals: list.length, list }; }
download(list, fileName) { if (!fileName) return; const url = window.URL.createObjectURL( new window.Blob([`\ufeff${list.join("\r\n")}`]) ); const link = document.createElement("a"); const evt = document.createEvent("MouseEvents"); link.href = url; link.setAttribute("download", fileName); evt.initEvent("click"); link.dispatchEvent(evt); }
完整代碼演示: https://codesandbox.io/s/beautiful-faraday-jt3i3?file=/src/App.js
getCheckedData() { return Table.getCheckedData(this.gridManagerName); } setCheckedData(checkedData) { Table.setCheckedData(this.gridManagerName, checkedData); } ajaxSuccess() { this.setCheckedData(this.state.selected); }
表格方法 getCheckedData 返回的是完整的已選數據,表格回顯的前提是傳入的數據和傳出的數據格式同樣,這在使用中會形成侷限,好比說後端並不會存儲完整的數據,而是隻存儲每條數據的 id,這是很常見的場景,所以在 GridManager 後面的迭代中,在 checkboxConfig 中添加了 key 屬性,只須要配置 key: 'id',在傳入的已選數據中,每條數據只須要包括 id 便可,不須要完整的數據結構也能夠完成回顯。
<Table checkboxConfig: { useRowCheck: true, key: 'id' }, />
onGridRowRender(row) { const disabledId = [69, 68]; if (disabledId.indexOf(row.id) > -1) { Object.assign(row, { gm_checkbox_disabled: true }); } return row; }
須要調用 checkedGridBefore 和 checkedGridAllBefore 這兩個方法來完成此需求,因爲觸發 checkedAllBefore 以後也會觸發 checkedBefore,所以這裏須要特殊處理一下,防止出現兩次 error 提示,詳細見下面的代碼實現。
checkedGridBefore = (checkedList, isChecked) => { if (checkedList.length >= MAX_NUM && !isChecked) { Message.error("最多支持同時選擇5個"); return false; } return true; }; checkedGridAllBefore(checkedList, isChecked) { const unChecked = this.dataList .map((item) => !checkedList.find((item1) => item.id === item1.id)) .filter(Boolean); if (unChecked.length + checkedList.length > MAX_NUM && !isChecked) { // 觸發 checkedAllBefore 以後也會觸發 checkedBefore,這裏須要特殊處理一下,防止出現兩次 error 提示 if (checkedList.length < MAX_NUM) { Message.error("最多支持同時選擇5個"); } return false; } return true; }
完整代碼演示:https://codesandbox.io/s/dazzling-albattani-o7dtn?file=/src/App.js
在表格基本配置的基礎上,添加 supportTreeData = true 以及 treeConfig 便可完成一個樹表格的展現。
... supportTreeData treeConfig={{ treeKey: "children" }} ...
完整代碼演示:https://codesandbox.io/s/shy-smoke-7ltz2?file=/src/App.js
設置 firstLoading = false,可讓表格先渲染出來,而後再加載數據。
使用場景:表格數據的請求返回較慢,這時,設置 firstLoading = false,表格就會先渲染,交互上會更加友好。
注意事項:須要配合 callback 函數使用,在 callback 函數中調用刷新表格的方法。
reloadGrid(gotoPage) { Table.setQuery(this.gridManagerName, this.queryParams, gotoPage); } gridInit = () => { this.reloadGrid(1); }; render() { return ( <div className="App"> <Table gridManagerName={this.gridManagerName} disableLine supportAjaxPage ajaxData={this.ajaxData} columnData={this.columnData} supportCheckbox={false} firstLoading={false} callback={this.gridInit} /> </div> ); }
完整代碼演示:https://codesandbox.io/s/quirky-https-k06m9?file=/src/App.js
能夠設置表頭的icon圖標是否跟隨文本,默認圖標是在左側,設置後會跟在文本右側
columnData = [ { key: "name", text: "名稱", align: "left", sorting: "", // 表頭 tooltip 配置 remind: { text: "字段說明字段說明字段說明字段說明字段說明字段說明", style: { "text-align": "left" } } } ]; render() { return ( <div className="App"> <Table gridManagerName={this.gridManagerName} disableLine supportAjaxPage ajaxData={this.ajaxData} columnData={this.columnData} supportCheckbox={false} isIconFollowText /> </div> ); }
完整代碼演示:https://codesandbox.io/s/interesting-dust-wwe85?file=/src/App.js:574-1194
在拖拽的場景中,若是涉及到表格的新增和刪除,不要直接對 ajaxData 進行操做,操做原數據,ajaxData 由原數據包裝而來,從而保證單一職責(詳細栗子請看完整代碼)。
ajaxData = async (settting, params) => { return Promise.resolve({ data: this.state.dataList, // dataList:原數據 totals: this.state.dataList.length }); }; onAdd() { const { dataList } = this.state; // dataList:原數據 dataList.push({ id: new Date().getTime(), name: "瀏覽器的工做原理" }); this.setState({ dataList }); this.reloadGrid(); } render() { const moveRowConfig = { key: "priority", handler: (list, tableData) => { console.log(tableData); }, useSingleMode: true // 第一列顯示拖拽圖標 }; return ( <div className="App"> <Button onClick={() => this.onAdd()}>新增</Button> <Table gridManagerName={this.gridManagerName} disableLine supportAjaxPage={false} ajaxData={this.ajaxData} columnData={this.columnData} supportCheckbox={false} supportMoveRow moveRowConfig={moveRowConfig} /> </div> ); }
完整代碼演示:https://codesandbox.io/s/jovial-water-8y4if?file=/src/App.js
使用場景:須要展現的列比較多或者有隱藏列的需求。
使用:在 columnData 數組新增一項配置便可
{ key: "operate", disableCustomize: true, text: ( <Icon type="config" style={{ cursor: "pointer", fontWeight: "bold" }} onClick={() => this.onSetUpGridFiled()} /> ), template: () => "", width: "30px" } onSetUpGridFiled() { Table.setConfigVisible(this.gridManagerName, true); }
完整代碼演示:https://codesandbox.io/s/sharp-perlman-1elht?file=/src/App.js:1094-1174