[Ext JS 4] 实战之Grid, Tree Gird 动态添加列

前言

在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}
写一个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();
				  }		  
			  }
		}
	}		 
}

在grid 创建完或是reconfig 的时候调用这个方法,问题解决。



你可能感兴趣的:([Ext JS 4] 实战之Grid, Tree Gird 动态添加列)