Extjs高級應用(一):實現GridPanel的單元格多選模組 – JAVA編程語言程序開發技術文章

  之前在項目中突然遇見一個很奇怪的需求,要求單元格能和Excel一樣進行多選,比如框選其中一個矩形區域,然後復制到同頁面另一個Grid中!!並添加統計報表功能。當時這個需求就把我們都怔住瞭!很變態很強悍的需求,因為這個模塊是一個基於報表的統計功能,使用瞭一個第三方的報表工具,但是頁面展示非常難看。。。。。客戶就對我們說,為什麼不用Ext來制作報表呢。呵呵最後當時是被我們回絕瞭,因為這確實是對我們團隊來說難度太大,而且成本太高。具備統計功能的Ext Grid再加上可編輯等等,就幾乎是一個網頁版的Excel瞭,我們不認為我們團隊能和Google Doc叫板…….

    但是事後我看瞭看 CellSelectionModel 和 RowSelectionModel的源代碼,發現單元格多選並不難,於是先沒和項目經理說我的想法,而是抽時間沒事研究瞭一下,終於搞瞭幾天之後,初版的模型就出來,嘿嘿現在嘗試著說服項目經理應用在系統中。OK,先上代碼和理論知識吧:


先說說Ext GridPanel UI組件的結構,它由五個部分組成,GridView、ColumnModel、SelectionModel、Store、GridPanel,不得不佩服Ext團隊的設計理念,這是一個典型的MVC結構組件。GridView負責管理表格的內容展示,ColumnModel負責列的定義,SelectionModel是選擇模組,Store是數據層,最後它們全部組合在一起由GridPanel進行渲染,展現在我們的面前。因為隻關註單元格多選,對我們有用的組件隻有Gridview 和 SelecitonModel。


    Grid選擇模型的實現原理是這樣的:Ext組件關系非常復雜,這裡用圖表進行說明吧


    


左側是加載初始化時的操作,右側是觸發事件時的操作。


現在我們自定義的SelectionModel 主要關註於handleMouseDown方法就行。我們的多選規則和Excel一樣,按住shift這是區域全選,按住ctrl則是添加被選中的單元格


Ext.hl.MultiCellSelectionModel = Ext.extend(Ext.grid.CellSelectionModel, {

last : false, // 上一次選中的單元格
selections : [], // 選擇區緩存

constructor : function() {
Ext.hl.MultiCellSelectionModel.superclass.constructor.call(this);
},
initEvents : function() {
Ext.hl.MultiCellSelectionModel.superclass.initEvents.call(this);
},
// 根據行列以及是否按住Ctrl鍵或者shift鍵,執行多選操作的邏輯
handleMouseDown : function(grid, row, col, event) {
var isSelected;
if(event.button !== 0 || this.isLocked())
return;
if(event.shiftKey && this.last !== false) { //是否按下shift
this.selectMatrix(row, col);
grid.getView().focusCell(row, col);
return;
} else if(event.ctrlKey){ //是否按下ctrl
isSelected = this.isSelected(row,col);
if (col === 0 && this.last[1] === 0){
isSelected ? this.deselectRow(row) : this.selectRow(row,true);
}
if(isSelected){ // 是否已被選中,是則反選,否則選中
this.deselectCell(row, col);
} else {
this.selectCell(row,col,true);
this.last = [row, col];
}
} else if (col === 0){ // 第一列是NumberColumn 點擊則選擇列
this.selectRow(row);
this.last = [row, col];
} else { // 選擇單個單元格
this.selectCell(row,col);
this.last = [row, col];
}
if(this.matrix)
delete this.matrix;
},
// 清楚選擇區內所以單元格被選中的樣式
clearCellSelections : function(){
var l <SPAN

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。