本篇這裡以稍微複雜一點的Tree Grid 來介紹.
在寫編輯grid 之, 先來看一下 grid 的 selType 的配置。
先給一個簡單的Tree grid 的例子:
Ext.onReady(function(){var treeStore = Ext.create('Ext.data.TreeStore', { fields: ['id','name','sex','age'], root:{ "children":[{id:'001',name:'shu',sex:'',age:'',expanded: true, "children":[{id:'001_1',name:'liu.bei',sex:'male',age:'50'}, {id:'001_2',name:'guan.yu',sex:'male',age:'49'}, {id:'001_3',name:'zhang.fei',sex:'male',age:'48'}] }] }}); var gridCols = [{xtype: 'treecolumn',text:'ID',dataIndex:'id'}, {text:'Name',dataIndex:'name'}, {text:'Sex',dataIndex:'sex'}, {text:'Age',dataIndex:'age'}];var treeGrid = Ext.create('Ext.tree.Panel',{title: 'Three KingDom',rootVisible: false,collapsible: true,store: treeStore,columns: gridCols,renderTo: Ext.getBody()});});
預設情況下, 點擊的時候是整行選取。
可以通過配置selType 進行配置, setType 配置的是 Ext.selection包下的Select Model 的 xtype.
可以配置:
1. rowmodel. 行選取, 預設的方式, 如果沒有設定selType的話使用這個。
2. cellmodel。 儲存格選取。
3. checkboxmodel。 checkbox 選取, 配置這個的話,會在grid 前加一列 check box 列
4. treemodel。
好了, 進入正題。對grid 進行編輯。
要對grid 進行編輯,需要以下兩個步驟:
1. 給grid 添加edit 的 plugin
var cellEditPlugin = Ext.create('Ext.grid.plugin.CellEditing', { clicksToEdit: 1 });var treeGrid = Ext.create('Ext.tree.Panel',{title: 'Three KingDom',rootVisible: false,collapsible: true,store: treeStore,columns: gridCols,plugins: [cellEditPlugin],renderTo: Ext.getBody()});
clicksToEdit : 1 是單擊, 2 是雙擊
2. columns 中需要編輯的列添加 editor
{text:'Name',dataIndex:'name',editor:{xtype:'textfield'}},
xtype 是編輯狀態的組件, 是簡單文字框,還是下拉單,或是其他的
有了以上 cell 模式, Row 模式就簡單了。
只是plugin 換成RowEditing 就可以了
var rowEditPlugin = Ext.create('Ext.grid.plugin.RowEditing', { clicksToEdit: 2 })
而且這兩種方式是可以並存的, 全部添加到grid 的plugins 的配置中就可以了。
不管是在row 或是cell的編輯模式下, 一次只能操作一行或一個儲存格。
要編輯下一個, 當前的這個就會回到非編輯狀態。
也就是, 看起來,只構造了一個editor 的組件, 大家輪著使用。
可是問題是, 如果有eidt all 這個按鈕的話,點擊之後, 所有可編輯的cell 全部置為編輯狀態,使用現有的配置目前就無法達到了。
在 Ext 3 之前的版本, Ext js 的開發人員有開發一個外掛程式解決這個問題:
http://www.sencha.com/forum/showthread.php?79232-EditableGrid-Shows-editors-for-all-cells
但是,也特別提出了,如果grid 的資料量很大的話, 這種方式的效能就不行了。
想想也是, 每個edit欄位都會建立一個複雜的組件, 效能肯定會受影響。
問題到這並沒有解決, 那個外掛程式只是在Ext 3 (或者以下)可以使用, 目前Ext 已經是 4 版本了。
Extjs 4 中並沒有直接解決方案, 升級那個外掛程式應該也挺費時的。
另外一種解法是在 配置col 的 render :
renderer:function(value, metadata,record){}
在列顯示之前, 把value 替換成<input >這種輸入框。 看上去不錯。
但是如果需要的是commobox 的話呢,
1. renderer 只能返回字串, 不能返回組件
2. field 組件本身也沒有直接轉成html 的方法。
3 自行組成 Ext js 的 commobox 的html 看上去也挺麻煩。
不過思路上還是要朝這個方向前進。 幸運的是已經有人把這個擴充完成了(在ext js 4之上)
http://skirtlesden.com/ux/component-column
使用方式很簡單, 現在兩個js 檔案
1.ctemplate.js
http://skirtlesden.com/ux/ctemplate
2. component.js
http://skirtlesden.com/ux/component-column
匯入後, 如下方式定義 col
{ ... dataIndex: 'status', xtype: 'componentcolumn', renderer: function(status) { return { ... store: ['Available', 'Away', 'Busy', 'Offline'], value: status, xtype: 'combobox' }; } }