在Ext js 中, 定义一个Grid 很方便,主要需要的是
1. 定义columns
2. 定义一个store
3. 定义grid
var store1 = Ext.create('Ext.data.TreeStore', { fields: ['task1','task2','task3'], root:{ "text": ".", "children": [{'task1':'11','task2':'22','task3':'33'}] } }); var treeGrid1 = Ext.create('Ext.tree.Panel',{ header: 'Test Grid', renderTo: Ext.getBody(), collapsible: true, rootVisible: false, autoScroll: true, height: 600, store: store1, columns: [{"text":"Task 1","dataIndex":"task1"}, {"text":"Task 2","dataIndex":"task2"}, {"text":"Task 3","dataIndex":"task3"}] });
要动态添加一列, 也很简单
使用 Grid 的 reconfigure 方法就可以了。
var cols1 = [{"text":"Task 1","dataIndex":"task1"}, {"text":"Task 2","dataIndex":"task2"}, {"text":"Task 3","dataIndex":"task3"} ]; var store1 = Ext.create('Ext.data.TreeStore', { fields: ['task1','task2','task3'], root:{ "text": ".", "children": [{'task1':'11','task2':'22','task3':'33'}] } }); var treeGrid1 = Ext.create('Ext.tree.Panel',{ header: 'Test Grid', renderTo: Ext.getBody(), collapsible: true, rootVisible: false, autoScroll: true, height: 600, store: store1, columns: cols1 }); //dynamic add col cols1.push({"text":"Task 4","dataIndex":"task4"}); treeGrid1.reconfigure(store1,cols1);
配置行编辑的plugin 为Ext.grid.plugin.RowEditing, 设置某列编辑的editor
var cols1 = [{"text":"Task 1","dataIndex":"task1"}, {"text":"Task 2","dataIndex":"task2",editor:{xtype:"textfield"}}, {"text":"Task 3","dataIndex":"task3"} ]; var store1 = Ext.create('Ext.data.TreeStore', { fields: ['task1','task2','task3'], root:{ "text": ".", "children": [{'task1':'11','task2':'22','task3':'33'}] } }); var treeGrid1 = Ext.create('Ext.tree.Panel',{ header: 'Test Grid', renderTo: Ext.getBody(), collapsible: true, rootVisible: false, autoScroll: true, height: 600, store: store1, columns: cols1, plugins:[Ext.create('Ext.grid.plugin.RowEditing', { clicksToMoveEditor: 2, autoCancel: false })] }); //dynamic add col cols1.push({"text":"Task 4","dataIndex":"task4"}); treeGrid1.reconfigure(store1,cols1);
下面要进入重点了
现在有个需求是某个栏位默认是隐藏的。默认隐藏也很容易实现,直接设置hidden 为 true 就可以了。
比如说以上设置Task 2 这一列的hidden 为true 的话
var cols1 = [{"text":"Task 1","dataIndex":"task1"}, {"text":"Task 2","dataIndex":"task2",editor:{xtype:"textfield"},"hidden":true}, {"text":"Task 3","dataIndex":"task3"} ]; var store1 = Ext.create('Ext.data.TreeStore', { fields: ['task1','task2','task3'], root:{ "text": ".", "children": [{'task1':'11','task2':'22','task3':'33'}] } }); var treeGrid1 = Ext.create('Ext.tree.Panel',{ header: 'Test Grid', renderTo: Ext.getBody(), collapsible: true, rootVisible: false, autoScroll: true, height: 600, store: store1, columns: cols1, plugins:[Ext.create('Ext.grid.plugin.RowEditing', { clicksToMoveEditor: 2, autoCancel: false })] }); //dynamic add col cols1.push({"text":"Task 4","dataIndex":"task4"}); treeGrid1.reconfigure(store1,cols1);
以上代码运行就会出现错误:
Uncaught TypeError: Object [object Object] has no method 'hasEditor'
究其原因是:
1. Edit 的plugin 在初始化时会调用initFieldAccessors(columns)这个方法。 对每个列添加hasEditor 和 Editor 相关的一些方法和对象。
但是这里获取columns 的方法是 grid.getView().getGridColumns()
也就是说, hidden 的col 不会被找到
2. 而在执行reconfigure的时候又会用到hasEditor这个方法。导致找不到出错。
想到的解决思路有很多中:
1. 修改extjs 的 js 文件, 做非空判断。
这种方法需要修改 ext 本身的东西, 对于升级和维护的话都不是很好。
2. 还是从hasEditor这个方法入手。 对于hidden 类型的 col , 添加一个空的hasEditor方法。类似
{"text":"Task 2","dataIndex":"task2",editor:{xtype:"textfield"},"hidden":true:hasEditor:function(){}}错误是解决了。
在view 的状态下是可以, 但是在edit 状态时, 编辑框的位置会错位,跑到最后面去。
3. 从plugin 入手。
以上方法不行,是否是因为不仅仅是要设置hasEditor,如果这样,模拟它本身的处理方式,调用initFieldAccessors(注意这个方法是 plugin 的)
plugin.initFieldAccessors(treeGrid.headerCt.getGridColumns());
var cols1 = [{"text":"Task 1","dataIndex":"task1"}, {"text":"Task 2","dataIndex":"task2",editor:{xtype:"textfield"},"hidden":true}, {"text":"Task 3","dataIndex":"task3"} ]; var store1 = Ext.create('Ext.data.TreeStore', { fields: ['task1','task2','task3'], root:{ "text": ".", "children": [{'task1':'11','task2':'22','task3':'33'}] } }); var plugin1 = Ext.create('Ext.grid.plugin.RowEditing', { clicksToMoveEditor: 2, autoCancel: false }); var treeGrid1 = Ext.create('Ext.tree.Panel',{ header: 'Test Grid', renderTo: Ext.getBody(), collapsible: true, rootVisible: false, autoScroll: true, height: 600, store: store1, columns: cols1, plugins:plugin1 }); plugin1.initFieldAccessors(treeGrid1.headerCt.getGridColumns()); //dynamic add col cols1.push({"text":"Task 4","dataIndex":"task4"}); treeGrid1.reconfigure(store1,cols1);
看来此种状况无法使用hidden 来隐藏栏位了。
既然无法通过config 的方式隐藏, 在grid 创建出来之后使用 hide()方法来隐藏总可以吧。
配置的时候给一个 hiddencol 的名字(可以随便取)
{"text":"Task 2","dataIndex":"task2",hiddencol:true}写一个function
function hideGridCols(grid) { if(grid!=null) { var gridCols = grid.headerCt.getGridColumns(); if(gridCols!=null&&gridCols.length>0) { for(var i=0;i<gridCols.length;i++) { var gridCol = gridCols[i]; var cfg = gridCol.initialConfig; if(cfg.hiddencol!=null&&cfg.hiddencol===true) { gridCol.hide(); } } } } }