自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

miniui datagrid的客戶端分頁解決方案

開發(fā) 前端
首先,是綁定一個 preload 事件,在這個事情中設(shè)置 event.cancel = true,阻止 datagrid 在翻頁的時候向服務(wù)器請求加載數(shù)據(jù)。那么數(shù)據(jù)從哪來呢?當(dāng)然只有在外部寫一個 ajax 過程獲取了。不過取得的數(shù)據(jù)并不直接交給 datagrid,而是緩存起來,放在 dataResult 中。

[[174396]]

官方的解決方案

官方在“在線示例”中給了一個簡單的 client pagination 解決方案,代碼就不貼了,這里說說它的基本思想和處理過程。

首先,是綁定一個 preload 事件,在這個事情中設(shè)置 event.cancel = true,阻止 datagrid 在翻頁的時候向服務(wù)器請求加載數(shù)據(jù)。

那么數(shù)據(jù)從哪來呢?當(dāng)然只有在外部寫一個 ajax 過程獲取了。不過取得的數(shù)據(jù)并不直接交給 datagrid,而是緩存起來,放在dataResult 中。

現(xiàn)在繼續(xù)說 preload,除了阻止 datagrid 向服務(wù)器請求數(shù)據(jù)之外,preload 還需要從緩存中找到頁碼對應(yīng)的數(shù)據(jù)行,通過 setData設(shè)置給 datagrid 渲染出來。OK,這個事情是交給自定義函數(shù) fillData 來實(shí)現(xiàn)的。當(dāng)然,這里還要干點(diǎn)與頁面相關(guān)的事情,就是setTotalCount()、setPageIndex() 和 setPageCount()。

官方的解決方案展示了 miniui datagrid 客戶端分頁解決方案的基本思想,但是這個示例太過簡單。如果,想把之前的服務(wù)端分頁改成客戶端分頁該怎么辦?原來已經(jīng)存在對 load()、setData() 等的調(diào)用,現(xiàn)在怎樣以最小的代碼改動來實(shí)現(xiàn)客戶端分頁?

class ClientPagination

就上面的問題,首先能想到的,就是保留原有 load() 和 setData() 的接口,但是要改變它們的行為。

  • load() 原有行為是提交了〔XXX參數(shù)〕,從服務(wù)器加載指定頁的數(shù)據(jù);而現(xiàn)在需要改為加載所有數(shù)據(jù)。
  • setData() 原來是向 datagrid 設(shè)置了需要顯示的所有數(shù)據(jù)行,不管分頁(比如可以一次顯示出來200條數(shù)據(jù));而現(xiàn)在,如果設(shè)置的數(shù)據(jù)量過大,則需要通過客戶端分頁來逐頁顯示。

JavaScript 語言是動態(tài)有,這使得替換方法成為可能,這是很多靜態(tài)語言做不到的事情。而替換方法也是解決這個問題時最容易想到的辦法。當(dāng)然除此之外,還得慶幸 miniui 沒有采用 jQuery 擴(kuò)展的方式(如 $grid.datagrid("setData", ...))來實(shí)現(xiàn)組件。

替換方法成為可能,但是原有方法還是得保留,因?yàn)槲覀冃枰ㄟ^原有方法來操作 datagrid。所以 ClientPagination 類應(yīng)該是這個樣子:

ClientPagination 的基本結(jié)構(gòu)

注:本文中所有代碼都是 ES6 語法 

  1. const METHODS = ["setData""load"]; 
  2.  
  3. class ClientPagination { 
  4.     constructor(datagrid) { 
  5.         this._datagrid = datagrid; 
  6.         this._origin = {}; 
  7.         this.setup(); 
  8.     } 
  9.      
  10.     setup() { 
  11.         // TODO 暫存 this._datagrid 的 load、setData 等方法 
  12.         // 并為 this._datagrid 設(shè)置新方法和注冊事件 
  13.     } 
  14.  
  15.     destroy() { 
  16.         // TODO 恢復(fù) this._datagrid 的方法,注銷事件 
  17.     } 
  18.      
  19.     onBeforeLoad() { 
  20.         // 根據(jù)官方的解決方案而來 
  21.         e.cancel = true
  22.         let pageIndex = e.data.pageIndex; 
  23.         let pageSize = e.data.pageSize; 
  24.         this.setPageData(pageIndex, pageSize); 
  25.     } 
  26.  
  27.     // 參照 datagrid.load 的函數(shù)簽名 
  28.     load(params, success, fail) { 
  29.         // TODO 實(shí)現(xiàn)加載數(shù)據(jù),并保存到 this._data 中 
  30.         // 然后調(diào)用 this.setData() 保存和顯示數(shù)據(jù) 
  31.     } 
  32.  
  33.     setData(data) { 
  34.         // TODO 保存 data 到 this._data 中, 
  35.         // 然后調(diào)用 this.setPageData() 顯示當(dāng)前頁的數(shù)據(jù) 
  36.     } 
  37.      
  38.     setPageData(pageIndex, pageSize) { 
  39.         // TODO 從緩存的 this._data 中按 pageIndex 和 pageSize 取出要顯示的數(shù)據(jù)行 
  40.         // 然后通過 this._origin.setData() 設(shè)置在 datagrid 中 
  41.     } 
  42.  

設(shè)置和解除客戶端分頁

其中 setup 和 destroy 為分別為 datagrid 綁定和解綁客戶端分頁處理

  1. setup() { 
  2.        const grid = this._datagrid; 
  3.        const original = this._origin = {}; 
  4.  
  5.        METHODS.forEach(name => { 
  6.            // 暫存原方法 
  7.            origin[name] = grid[name].bind(grid); 
  8.            // 替換為本類中定義的新方法 
  9.            grid[name] = this[name].bind(this); 
  10.        }); 
  11.  
  12.        // 暫存事件處理函數(shù),以便后面注銷 
  13.        this._onBeforeLoad = this.onBeforeLoad.bind(this); 
  14.        grid.on("beforeload", this._onBeforeLoad); 
  15.    } 
  16.  
  17.    destroy() { 
  18.        this._origin = {}; 
  19.        this._datagrid.un("beforeload", this._onBeforeLoad); 
  20.        this._datagrid = null
  21.    }  

來自官方示例中的關(guān)鍵代碼

onBeforeLoad 以及 setPageData 是參照官方解決方案中的 beforeload 事件和 fillData 方法寫的。onBeforeLoad 的代碼在上面已經(jīng)有了,現(xiàn)在是 setPageData 的代碼

  1. setPageData(pageIndex, pageSize) { 
  2.         const allData = this._data; 
  3.         let start = pageIndex * pageSize; 
  4.         if (start >= allData.length) { 
  5.             start = 0; 
  6.             pageIndex = 0; 
  7.         } 
  8.         const end = Math.min(start + pageSize, allData.length); 
  9.  
  10.         const pageData = []; 
  11.         for (let i = start; i < end; i++) { 
  12.             pageData.push(allData[i]); 
  13.         } 
  14.  
  15.         const grid = this._datagrid; 
  16.         grid.setTotalCount(allData.length); 
  17.         grid.setPageIndex(pageIndex); 
  18.         grid.setPageSize(pageSize); 
  19.         this._origin.setData(pageData); 
  20.     }  

改寫 load

load 方法需要用 ajax 調(diào)用來替換原來的 load 方法 

  1. load(params, success, fail) { 
  2.         const grid = this._datagrid; 
  3.         const url = grid.getUrl(); 
  4.  
  5.         const settings = { 
  6.             type: "post"
  7.             dataType: "json"
  8.             data: params || {} 
  9.         }; 
  10.  
  11.         $.ajax(url, settings) 
  12.             .then(data => { 
  13.                 this.setData(data); 
  14.                 if (typeof success === "function") { 
  15.                     success(data); 
  16.                 } 
  17.             }, () => { 
  18.                 if (typeof fail === "function") { 
  19.                     fail(); 
  20.                 } 
  21.             }); 
  22.     }  

改寫 setData

而 setData 也進(jìn)行了替換,參數(shù)是整表的數(shù)據(jù),但只能顯示當(dāng)前頁的數(shù)據(jù)

  1. setData(data) { 
  2.         const rows = Array.isArray(data) 
  3.             ? data 
  4.             : (data.data || []); 
  5.  
  6.         this._data = rows
  7.         this.setPageData(this._datagrid.getPageIndex(), this._datagrid.getPageSize()); 
  8.     }  

應(yīng)用

為了方便封裝,再加一個靜態(tài)方法

  1. static wrap(datagrid) { 
  2.         return new ClientPagination(datagrid); 
  3.     }  

現(xiàn)在只需要在頁面初始化(或其它合適的初始化位置)加上

  1. ClientPagination.wrap(mini.get("datagridId")); 

如果需要 destroy,可以這樣

  1. var cpBlabla = ClientPagination.wrap(mini.get("datagridId")); 
  2. .... 
  3. cpBalbal.destory();  

小結(jié)

通過 ClientPagination 的封裝,不需要改變原有的業(yè)務(wù)代碼和設(shè)置,就可以實(shí)現(xiàn) miniui datagrid 的客戶端分頁。

但是這個實(shí)現(xiàn)只是解決了當(dāng)前的問題,如果有新的需求:

當(dāng)頁碼在前三頁的時候用客戶端分頁,以減少數(shù)據(jù)加載次數(shù),翻到后面的時候需要用服務(wù)器端分頁

責(zé)任編輯:龐桂玉 來源: segmentfault
相關(guān)推薦

2013-05-30 17:52:06

2019-09-08 16:45:19

JavaScriptHTML5GitHub

2012-12-18 09:34:49

2014-06-18 10:25:31

戴爾

2009-12-30 15:29:14

2021-10-04 09:14:18

ElasticSear深度分頁

2014-08-01 18:26:49

戴爾

2021-09-22 15:46:29

虛擬桌面瘦客戶端胖客戶端

2025-04-27 02:22:00

分頁項目開發(fā)

2012-09-04 09:40:01

2011-06-08 22:06:04

工作站解決方案

2010-08-06 14:13:31

FlexDataGrid分頁控

2010-03-17 18:04:55

java Socket

2011-03-21 14:53:36

Nagios監(jiān)控Linux

2011-04-06 14:24:20

Nagios監(jiān)控Linux

2009-11-05 13:08:44

WCF客戶端配置

2011-08-17 10:10:59

2011-03-02 14:36:24

Filezilla客戶端

2010-12-21 11:03:15

獲取客戶端證書

2011-03-24 13:00:31

配置nagios客戶端
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號