使用
ExtJS-5.10
的GridPanel
组件实现表格嵌套,主要依赖于GridPanel
自带的RowExpander
插件,具体用法以及配置参数请参照API 这里有一个简单的表格嵌套Demo和大家分享,此Demo采用的是ExtJS MVC模式,要求对ExtJS 具有一定的了解。
- 入口文件配置 SGEntry.js
Ext.application({
name:'SubGrid',
autoCreateViewport: 'SubGrid.view.SubGridMain',
//将视图模型加载到项目中
controllers:['SubGridController']
});
- 视图层外层Grid SubGridMain.js 和嵌套Grid InnerGrid.js 定义
Ext.define('SubGrid.view.SubGridMain', {
extend : 'Ext.grid.Panel',
title : 'SubGridTest',
alias : 'widget.outerGrid',
store : 'SubGridStore',
forceFit : true,
selModel : {
selType: 'cellmodel',
mode:'SIMPLE',
},
//该段为主表添加RowExpander插件,并指定展开区域的div标签以及类,用于承载子表
plugins : {
//指明插件類型
ptype : 'rowexpander',
//指明行展开区域
rowBodyTpl :["<div class='customer_expand_area_cls'>","</div>"],
},
initComponent : function() {
Ext.apply(this, {
columns : [ {
header : 'Name',
dataIndex : 'name',
align : 'center'
}, {
header : 'Email',
dataIndex : 'email',
align : 'center'
}, {
header : 'Phone',
dataIndex : 'phone',
align : 'center'
} ]
});
this.callParent(arguments);
},
})
Ext.define('SubGrid.view.InnerGrid', {
extend : 'Ext.grid.Panel',
alias : 'widget.innerGrids',
store : 'InnerGridStore',
forceFit : true,
border : false,
selModel : {
selType: 'cellmodel',
mode:'SIMPLE',
},
initComponent : function() {
/*
* 表格嵌套时必须重写Ext.view.Table,否则报错因为事件链调用的原因。
*/
Ext.define('SystemFox.overrides.view.Table', {
override : 'Ext.view.Table',
checkThatContextIsParentGridView : function(e) {
var target = Ext.get(e.target);
var parentGridView = target.up('.x-grid-view');
if (this.el != parentGridView) {
return false;
} else {
return true;
}
},
processItemEvent : function(record, row, rowIndex, e) {
if (e.target && !this.checkThatContextIsParentGridView(e)) {
return false;
} else {
return this.callParent([ record, row, rowIndex, e ]);
}
}
});
Ext.apply(this, {
columns : [ {
text : 'Name',
dataIndex : 'name',
sortable : true,
align : 'center'
}, {
text : 'Email',
dataIndex : 'email',
sortable : true,
align : 'center'
}, {
text : 'Phone',
dataIndex : 'phone',
sortable : true,
align : 'center'
},{
text : 'Age',
dataIndex : 'age',
sortable : true,
align : 'center'
} ,{
text : 'Address',
dataIndex : 'address',
sortable : true,
align : 'center'
}],
});
this.callParent(arguments);
},
})
- 数据源层定义SubGridStore.js 和 InnerGridStore.js
Ext.define('SubGrid.store.SubGridStore',{
extend:'Ext.data.Store',
model:'SubGrid.model.SubGridModel',
data : [ {
'name' : 'Lisa',
"email" : "lisa@simpsons.com",
"phone" : "555-111-1224"
}, {
'name' : 'Bart',
"email" : "bart@simpsons.com",
"phone" : "555-222-1234"
}, {
'name' : 'Homer',
"email" : "home@simpsons.com",
"phone" : "555-222-1244"
}, {
'name' : 'Marge',
"email" : "marge@simpsons.com",
"phone" : "555-222-1254"
} ]
})
Ext.define('SubGrid.store.InnerGridStore',{
extend:'Ext.data.Store',
model:'SubGrid.model.InnerGridModel',
data : [ {
'name' : 'LisaInnerGridData',
"email" : "lisa@simpsons.com",
"phone" : "555-111-1224-Inner",
"age":26,
"address":"Beijing"
}, {
'name' : 'BartLisaInnerGridData',
"email" : "bart@simpsons.com",
"phone" : "555-222-1234-Inner",
"age":26,
"address":"Beijing"
}, {
'name' : 'HomerLisaInnerGridData',
"email" : "home@simpsons.com",
"phone" : "555-222-1244-Inner",
"age":26,
"address":"Beijing"
}, {
'name' : 'MargeLisaInnerGridData',
"email" : "marge@simpsons.com",
"phone" : "555-222-1254-Inner",
"age":26,
"address":"Beijing"
} ]
})
- 模型层定义SubGridModel.js 和 InnerGridModel.js
Ext.define('SubGrid.model.SubGridModel', {
extend : 'Ext.data.Model',
fields:['name','email','phone']
})
Ext.define('SubGrid.model.InnerGridModel', {
extend : 'Ext.data.Model',
fields:['name','email','phone','age','address']
})
- 最后控制层定义SubGridController.js
Ext.define('SubGrid.controller.SubGridController', {
extend : 'Ext.app.Controller',
stores : [ 'SubGridStore', 'InnerGridStore' ],
models : [ 'SubGridModel', 'InnerGridModel' ],
views : [ 'SubGridMain', 'InnerGrid' ],
init : function() {
this.control({
//监听主表视图对应事件,注意该事件并非grid panel的事件,而是Ext.view.Table对应事件
//而RowExpander的事件会发送到grid panel view来监听执行,所以必须获取grid panle的gridview 来实现监听
'outerGrid gridview' : {
expandbody : this.rowExpandEventAction,
collapsebody:this.rowCollapseBodyAction
}
});
},
//展开子表
rowExpandEventAction : function(rowNode, record, expand_area, eopts) {
//创建子表,关于创建组件的方法,有很多,比如new ,或者create(),或者Ext.create(),在开发过程中具体选择哪种方式
//依赖于业务需求,自己判断,比如此时我要实现创建一个组件并渲染到指定区域,最简单的便是直接通过Ext.create来实现
//我们已定义组件因为我们需要添加额外的配置属性,倘若不需要添加,直接get**View().create()便可
Ext.create('SubGrid.view.InnerGrid', {
renderTo : expand_area.getElementsByClassName('customer_expand_area_cls')[0]
}).show();
},
//收起子表
rowCollapseBodyAction:function(rowNode, record, expand_area, eOpts){
//销毁子表时,我们仅需销毁组件渲染到的区域,那么该区域下的内容也会自动销毁
var div_expand=expand_area.getElementsByClassName('customer_expand_area_cls')[0];
div_expand.removeChild(div_expand.firstChild);
}
});
最后在页面引入入口文件SGEntry.js然后引入相应的
ext-all-debug.js 、ext-locale-en.js
等等需要的文件,最终运行效果如图: