鉴于表格的创建特别繁琐,extjs的论坛上有人用Dynamic Grid来做实现,但只是介绍了XML的形式。我就站在前人的肩膀上进行扩展吧。呵呵。
创建Dynamic Grid代码如下:
- // 重新扩展的grid组建
- Ext.namespace("Ext.grid");
- /**
- * 是否输出调试语句
- */
- var __isDebug = true;
- __log = function(str) {
- if (__isDebug) {
- try {
- Ext.log(str);
- } catch (e) {
- }
- }
- };
- var __hasChkBox = true;
- var __hasRowNum = true;
- var __chkbox = new Ext.grid.CheckboxSelectionModel();
- /**
- * 动态创建表格
- * @param config 创建参数
- */
- Ext.grid.DynamicEditorGridPanel = function(config) {
- //系统参数
- this.loadMask = {msg :'正在加载数据,请稍侯……'};
- this.bodyStyle = 'width:100%'; // 表格宽度为100%
- this.autoWidth = true; // 是否支持自动宽度
- this.height = 490; //
- this.autoHeight = false; // 是否支持自动高度
- this.viewConfig = {forceFit :true}; //自动列宽
- this.collapsible = true; //
- this.containerScroll = true; //是否支持滚动条
- this.autoScroll = true; //是否自动出现滚动条
- this.stripeRows = true;
- this.animCollapse = true;
- //自定义表格参数
- this.hasPage = true; // 是否需要分页工具栏,默认为true
- this.pageSize = Ext.parameter.pageSize;// 分页大小
- this.pagePlace = 'bbar'; // 分页工具栏位置
- this.hasChkBox = true; // 是否支持行复选框,默认为true
- this.hasRowNum = true; // 是否支持行自编号,默认为true
- this.metaMode = 'Json';
- //自定义数据参数
- this.readMode = 'Json'; //数据加载模式
- this.keyFild = ''; // 关键字
- this.dataUrl = ''; // 获取数据的URL
- this.totalProperty = 'totalProperty';
- this.root = 'rootList';
- this.metaFields = undefined;
- //自定义排序参数
- this.sort = true; //是否支持排序
- this.defaultSort = ''; // 默认排序字段
- this.defaultDir = 'DESC'; // 默认排序方式
- //自定义分组参数
- this.group = false; //是否支持分组
- this.groupField = ''; //默认分组字段
- for (var key in config) {
- //将前台的创建参数追个进行加载
- eval("this." + key + " = config." + key + ";");
- }
- Ext.grid.DynamicEditorGridPanel.superclass.constructor.call(this, this.renderTo,config);
- };
- /**
- * 动态创建表格实现
- */
- Ext.extend(Ext.grid.DynamicEditorGridPanel, Ext.grid.EditorGridPanel, {
- /**
- * 初始化函数
- */
- initComponent : function() {
- //加载数据
- this.initStore();
- //是否支持复选列和自编号列
- __hasChkBox = this.hasChkBox;
- __hasRowNum = this.hasRowNum;
- //加入复选列模式
- if(__hasChkBox){
- this.selModel = __chkbox;
- }
- //为查询框加入数据集
- this.initSearch();
- Ext.grid.DynamicEditorGridPanel.superclass.initComponent.call(this);
- },
- /**
- * 重写render函数
- * 创建一个空列
- * 创建数据装载事件
- */
- render : function() {
- //创建空列模型
- this.colModel = new Ext.grid.DefaultColumnModel( [ {
- header :"",
- dataIndex :""
- } ]);
- //创建数据加载时的事件
- this.store.addListener("load", this.doReconfiguration, this);
- //实现
- Ext.grid.DynamicEditorGridPanel.superclass.render.call(this);
- },
- /**
- * 调用动态创建列函数并将列加入表格view
- * 删除store的load装载事件
- */
- doReconfiguration : function() {
- var fields;
- if(this.metaMode === 'Json'){
- fields = this.store.reader.recordType.prototype.fields;
- }else if(this.metaMode === 'Array'){
- fields = this.metaFields;
- }
- this.colModel = new Ext.grid.DynamicColumnModel(this.store,fields,this.metaMode);
- this.view.bindColumnModel(this.colModel);
- this.view.refresh(true);
- this.colModel.defaultSortable = true;
- this.store.removeListener("load", this.doReconfiguration);
- },
- /**
- * 数据加载
- */
- initStore : function() {
- var myUrl = this.dataUrl,
- myField = this.defaultSort === '' ? this.keyFild : this.defaultSort,
- myDirection = this.defaultDir,
- myTotalProperty = this.totalProperty === '' ? 'totalProperty' : this.totalProperty,
- myRoot = this.root === '' ? 'rootList' : this.root,
- myPruneModifiedRecords = this.pruneModifiedRecords === true ? true : false;
- // 数据读取器用JSON方式读取数据
- var myReader;
- switch (this.readMode) {
- case 'Json':
- // 加载Json数据模式
- myReader = new Ext.data.DynamicJsonReader( {totalProperty :myTotalProperty,root :myRoot});
- break;
- case 'Xml':
- // 加载Xml数据模式,待扩展
- break;
- default:
- break;
- }
- //pruneModifiedRecords 每次进行remove和load时清除modified记录,避免下次提交会把脏modified记录提交
- var myDs = new Ext.data.Store( {url :myUrl,reader :myReader,pruneModifiedRecords: myPruneModifiedRecords});
- if(this.sort){
- //加载排序参数
- myDs.sortInfo = {field :myField,direction :myDirection}; //关键所在,要将排序字段赋给reader以备刷新所用
- myDs.remoteSort = true;
- }
- if(this.hasPage){
- var myLimit = this.pageSize;
- // 加载分页数据
- myDs.load( {
- params : {
- start :0,
- limit :myLimit
- }
- });
- //创建分页栏
- this.initPaging(myDs,myLimit);
- }else{
- // 加载全部数据
- myDs.load();
- }
- this.store = myDs;
- },
- /**
- * 为查询框加入数据集
- * 因为在前台加载grid的时候还没有创建store
- * 所以在本函数加载Ext.app.SearchField的数据store
- */
- initSearch :function() {
- var myStore = this.store;
- for(var i = 0;i < this.tbar.length; i++){
- if (this.tbar[i] instanceof Ext.app.SearchField){//判断本按钮是否为Ext.app.SearchField的实例如果为实例则为其加入数据
- var btn = this.tbar[i];
- btn.store = myStore;
- break;
- }
- }
- },
- /**
- * 加载分页
- */
- initPaging : function(myStore,myPageSize) {
- //判断是否需要创建分页栏
- var myBBar = new Ext.PagingToolbar( {
- pageSize :myPageSize, // 分页数
- store :myStore, // 填充数据
- displayInfo :true, // 是否显示文字信息
- displayMsg :'显示第 {0} 条到 {1} 条记录,一共 {2} 条', // 格式化文字信息
- emptyMsg :"没有数据记录..." // 没有数据时的提示
- });
- if(this.pagePlace === 'tbarANDbbar'){
- this.tbar = myBBar; // 加入顶部分页栏
- this.bbar = myBBar; // 加入底部分页栏
- }else if(this.pagePlace === 'tbar'){
- this.tbar = myBBar; // 加入顶部分页栏
- }else{
- this.bbar = myBBar; // 加入底部分页栏
- }
- },
- /**
- *
- */
- getRecordType : function(){
- return this.store.reader.recordType;
- },
- /**
- * 取修改的起始列数
- */
- getStartEditColNum : function(){
- var num = 0;
- num = this.hasChkBox === true ? num + 1 : num;
- num = this.hasRowNum === true ? num + 1 : num;
- return num;
- }
- });
- /**
- * 重构JsonReader
- * @param config
- */
- Ext.data.DynamicJsonReader = function (config) {
- Ext.data.DynamicJsonReader.superclass.constructor.call(this, config);
- };
- Ext.extend(Ext.data.DynamicJsonReader, Ext.data.JsonReader, {
- readRecords:function (o) {
- for(var key in this.meta){
- if(eval('o.metaData.'+key) === undefined){
- eval("o.metaData." + key + " = this.meta." + key + ";");
- }
- }
- return Ext.data.DynamicJsonReader.superclass.readRecords.call(this, o);
- }
- });
- /**
- * 动态创建表格列
- * @param store
- */
- Ext.grid.DynamicColumnModel = function(store,fields,metaMode) {
- var cols = [];
- var recordType = store.reader.recordType;
- // 添加自动编号列
- if (__hasRowNum) {
- var __rownum = new Ext.grid.RowNumberer({});
- cols[cols.length] = __rownum;
- }
- // 添加复选列
- if (__hasChkBox) {
- cols[cols.length] = __chkbox;
- }
- if(metaMode === 'Json'){
- for ( var j = 0; j < fields.keys.length; j++) {
- var fieldName = fields.keys[j];
- var field = recordType.getField(fieldName);
- createCols(field);
- }
- }else if(metaMode === 'Array'){
- for ( var k = 0; k < fields.length; k++) {
- createCols(fields[k]);
- }
- }
- /**
- * 创建列数组
- * @param field
- * @return
- */
- function createCols(field){
- if(field.create === undefined || field.create === true){//默认和true时创建列
- var colsLength = cols.length;
- cols[colsLength] = {//
- id :field.name, //String主要用于样式选择,如果已定义此属性,那么列所在的单元格会定义class为 x-grid-td-id
- header :field.header, //String 头部显示的名称
- dataIndex :field.name, //String 要绑定的Store之Record字段名
- align :(field.align === undefined || field.align === '' || field.align === null) ? (field.type == ('int' || 'float') ? 'right' : 'left') : field.align, //String css中的对齐方式
- width :(field.width === undefined || field.width <=0 || field.width === null) ? undefined : field.width, //宽度
- sortable :(field.sortable === undefined || field.sortable === true || field.sortable === null) ? true : false,//可排序
- hidden :(field.hidden === undefined || field.hidden === false || field.hidden === null) ? false : true,//列是否隐藏
- renderer :(field.renderer === undefined || field.renderer === '' || field.renderer === null) ? undefined : field.renderer,//事件
- editor :(field.editor === undefined || field.editor === '' || field.editor === null) ? undefined : eval('Ext.util.Editor.'+field.editor+'Editor')
- };
- }
- }
- store.fields = store.reader.recordType.prototype.fields;
- Ext.grid.DynamicColumnModel.superclass.constructor.call(this, cols);
- };
- /**
- * 动态创建表格列实现
- */
- Ext.extend(Ext.grid.DynamicColumnModel, Ext.grid.ColumnModel, {});
- /**
- * 绑定列事件
- * @param cm
- * @return
- */
- Ext.grid.GridView.prototype.bindColumnModel = function(cm) {
- if (this.cm) {
- this.cm.un("configchange", this.onColConfigChange, this);
- this.cm.un("widthchange", this.onColWidthChange, this);
- this.cm.un("headerchange", this.onHeaderChange, this);
- this.cm.un("hiddenchange", this.onHiddenChange, this);
- this.cm.un("columnmoved", this.onColumnMove, this);
- this.cm.un("columnlockchange", this.onColumnLock, this);
- }
- if (cm) {
- delete this.lastViewWidth;
- cm.on("configchange", this.onColConfigChange, this);
- cm.on("widthchange", this.onColWidthChange, this);
- cm.on("headerchange", this.onHeaderChange, this);
- cm.on("hiddenchange", this.onHiddenChange, this);
- cm.on("columnmoved", this.onColumnMove, this);
- cm.on("columnlockchange", this.onColumnLock, this);
- }
- this.cm = cm;
- };
该Dynamic Grid中实现了Json和Array两种形式动态创建表格(XML形式大家可以参考论坛上的例子)。
先来介绍Array的实现方式:
- var fields = [
- {"create":false,"header":" 系统角色编号","name":"roleId",type:"int"},
- {"header":" 系统角色名称","name":"roleName"
- {"header":" 是否启用","name":"roleIsforbid"},
- {"header":" 备注","name":"mem"
- ];
var grid = new Ext.grid.DynamicEditorGridPanel( {
renderTo :'divGrid',
keyFild :'roleId',//主键ID
dataUrl :webPath + '/role!ByList.action',//后台取JSON数据的地址- pruneModifiedRecords : true,
metaFields : fields,//事先定义的数组
metaMode :'Array'//动态创建表格的模式为'Array'模式
});
grid.render();
再来介绍Json的实现方式:
- var grid = new Ext.grid.DynamicEditorGridPanel( {
- renderTo :'divGrid',
- keyFild :'roleId',
- dataUrl :webPath + '/role!ByList.action'
- });
- grid.render();
在这里时应用了JsonReade里面的meta这个属性,所以后台一定要返回如下的数据格式:
- {"metaData":{"fields":[{"header":"***","name":"**","type":"**"},{"header":"***","name":"**","type":"**"}……]},
- "rootList":[{……}],"totalProperty":**}
需要注意的是,由于Dynamic Grid是在运行时生成ColumnModel,那么一旦Dynamic Grid的状态改变,如columnmove/columnresize/sortchange,当重新创建Dynamic Grid时(例如刷新页面后重新访问),ext会试图先从cookie中读取状态信息,而此时ColumnModel还没有生成,系统就会报错。所以,可考虑关闭状态管理器,或重写Grid的applyState()方法,在里面判断this.colModel是否存在.
需要注意的第二点是,如果用meta属性动态生成表格后的话.会出现一个不能正常排序的问题.我能想到的办法就是修改all-dug.js代码里面的内容。搜索“this.sortInfo = meta.sortInfo”这句修改为“this.sortInfo = this.sortInfo;”这样就可以正常运行了。
到此就完成了,最近工作上实在太忙了,只能抽空先丢出来,写的不好,大家原谅。如果有什么问题可以通过QQ:272123239或是MSN:wego516@hotmail.com联系我。
我会尽快完善代码。并上传实例和源码。