您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關miniui datagrid的客戶端分頁解決方法是怎樣的,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
官方的解決方法
官方在“在線示例”中給了一個簡單的 client pagination 解決方法,代碼就不貼了,這里說說它的基本思想和處理過程。
首先,是綁定一個 preload 事件,在這個事情中設置 event.cancel = true,阻止 datagrid 在翻頁的時候向服務器請求加載數據。
那么數據從哪來呢?當然只有在外部寫一個 ajax 過程獲取了。不過取得的數據并不直接交給 datagrid,而是緩存起來,放在dataResult 中。
現在繼續說 preload,除了阻止 datagrid 向服務器請求數據之外,preload 還需要從緩存中找到頁碼對應的數據行,通過 setData設置給 datagrid 渲染出來。OK,這個事情是交給自定義函數 fillData 來實現的。當然,這里還要干點與頁面相關的事情,就是setTotalCount()、setPageIndex() 和 setPageCount()。
官方的解決方案展示了 miniui datagrid 客戶端分頁解決方案的基本思想,但是這個示例太過簡單。如果,想把之前的服務端分頁改成客戶端分頁該怎么辦?原來已經存在對 load()、setData() 等的調用,現在怎樣以最小的代碼改動來實現客戶端分頁?
class ClientPagination
就上面的問題,首先能想到的,就是保留原有 load() 和 setData() 的接口,但是要改變它們的行為。
load() 原有行為是提交了〔XXX參數〕,從服務器加載指定頁的數據;而現在需要改為加載所有數據。
setData() 原來是向 datagrid 設置了需要顯示的所有數據行,不管分頁(比如可以一次顯示出來200條數據);而現在,如果設置的數據量過大,則需要通過客戶端分頁來逐頁顯示。
JavaScript 語言是動態有,這使得替換方法成為可能,這是很多靜態語言做不到的事情。而替換方法也是解決這個問題時最容易想到的辦法。當然除此之外,還得慶幸 miniui 沒有采用 jQuery 擴展的方式(如 $grid.datagrid("setData", ...))來實現組件。
替換方法成為可能,但是原有方法還是得保留,因為我們需要通過原有方法來操作 datagrid。所以 ClientPagination 類應該是這個樣子:
ClientPagination 的基本結構
注:本文中所有代碼都是 ES6 語法
const METHODS = ["setData", "load"]; class ClientPagination { constructor(datagrid) { this._datagrid = datagrid; this._origin = {}; this.setup(); } setup() { // TODO 暫存 this._datagrid 的 load、setData 等方法 // 并為 this._datagrid 設置新方法和注冊事件 } destroy() { // TODO 恢復 this._datagrid 的方法,注銷事件 } onBeforeLoad() { // 根據官方的解決方案而來 e.cancel = true; let pageIndex = e.data.pageIndex; let pageSize = e.data.pageSize; this.setPageData(pageIndex, pageSize); } // 參照 datagrid.load 的函數簽名 load(params, success, fail) { // TODO 實現加載數據,并保存到 this._data 中 // 然后調用 this.setData() 保存和顯示數據 } setData(data) { // TODO 保存 data 到 this._data 中, // 然后調用 this.setPageData() 顯示當前頁的數據 } setPageData(pageIndex, pageSize) { // TODO 從緩存的 this._data 中按 pageIndex 和 pageSize 取出要顯示的數據行 // 然后通過 this._origin.setData() 設置在 datagrid 中 } }
設置和解除客戶端分頁
其中 setup 和 destroy 為分別為 datagrid 綁定和解綁客戶端分頁處理
setup() { const grid = this._datagrid; const original = this._origin = {}; METHODS.forEach(name => { // 暫存原方法 origin[name] = grid[name].bind(grid); // 替換為本類中定義的新方法 grid[name] = this[name].bind(this); }); // 暫存事件處理函數,以便后面注銷 this._onBeforeLoad = this.onBeforeLoad.bind(this); grid.on("beforeload", this._onBeforeLoad); } destroy() { this._origin = {}; this._datagrid.un("beforeload", this._onBeforeLoad); this._datagrid = null; }
來自官方示例中的關鍵代碼
onBeforeLoad 以及 setPageData 是參照官方解決方案中的 beforeload 事件和 fillData 方法寫的。onBeforeLoad 的代碼在上面已經有了,現在是 setPageData 的代碼
setPageData(pageIndex, pageSize) { const allData = this._data; let start = pageIndex * pageSize; if (start >= allData.length) { start = 0; pageIndex = 0; } const end = Math.min(start + pageSize, allData.length); const pageData = []; for (let i = start; i < end; i++) { pageData.push(allData[i]); } const grid = this._datagrid; grid.setTotalCount(allData.length); grid.setPageIndex(pageIndex); grid.setPageSize(pageSize); this._origin.setData(pageData); }
改寫 load
load 方法需要用 ajax 調用來替換原來的 load 方法
load(params, success, fail) { const grid = this._datagrid; const url = grid.getUrl(); const settings = { type: "post", dataType: "json", data: params || {} }; $.ajax(url, settings) .then(data => { this.setData(data); if (typeof success === "function") { success(data); } }, () => { if (typeof fail === "function") { fail(); } }); }
改寫 setData
而 setData 也進行了替換,參數是整表的數據,但只能顯示當前頁的數據
setData(data) { const rows = Array.isArray(data) ? data : (data.data || []); this._data = rows; this.setPageData(this._datagrid.getPageIndex(), this._datagrid.getPageSize()); }
應用
為了方便封裝,再加一個靜態方法
static wrap(datagrid) { return new ClientPagination(datagrid); }
現在只需要在頁面初始化(或其它合適的初始化位置)加上
ClientPagination.wrap(mini.get("datagridId"));
如果需要 destroy,可以這樣
var cpBlabla = ClientPagination.wrap(mini.get("datagridId")); .... cpBalbal.destory();
通過 ClientPagination 的封裝,不需要改變原有的業務代碼和設置,就可以實現 miniui datagrid 的客戶端分頁。
但是這個實現只是解決了當前的問題,如果有新的需求:
當頁碼在前三頁的時候用客戶端分頁,以減少數據加載次數,翻到后面的時候需要用服務器端分頁
上述就是小編為大家分享的miniui datagrid的客戶端分頁解決方法是怎樣的了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。