前言
在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'
如果使用debug 的js 的话, 会报在107028.
究其原因是:
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}写一个functionfunction 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();
}
}
}
}
}在grid 创建完或是reconfig 的时候调用这个方法,问题解决。