Ext动态表格的Json和Array实现方式

        鉴于表格的创建特别繁琐,extjs的论坛上有人用Dynamic Grid来做实现,但只是介绍了XML的形式。我就站在前人的肩膀上进行扩展吧。呵呵。

        创建Dynamic Grid代码如下:

  1. // 重新扩展的grid组建
  2. Ext.namespace("Ext.grid");
  3. /**
  4.  * 是否输出调试语句
  5.  */
  6. var __isDebug = true;
  7. __log = function(str) {
  8.     if (__isDebug) {
  9.         try {
  10.             Ext.log(str);
  11.         } catch (e) {
  12.         }
  13.     }
  14. };
  15. var __hasChkBox = true;
  16. var __hasRowNum = true;
  17. var __chkbox = new Ext.grid.CheckboxSelectionModel();
  18. /**
  19.  * 动态创建表格
  20.  * @param config 创建参数
  21.  */
  22. Ext.grid.DynamicEditorGridPanel = function(config) {
  23.     
  24.     //系统参数
  25.     this.loadMask = {msg :'正在加载数据,请稍侯……'};
  26.     this.bodyStyle = 'width:100%';      // 表格宽度为100%
  27.     this.autoWidth = true;                  // 是否支持自动宽度
  28.     this.height = 490;                          //
  29.     this.autoHeight = false;                // 是否支持自动高度
  30.     this.viewConfig = {forceFit :true}; //自动列宽
  31.     this.collapsible = true;                    //
  32.     this.containerScroll =  true;           //是否支持滚动条
  33.     this.autoScroll = true;                     //是否自动出现滚动条
  34.     this.stripeRows = true;
  35.     this.animCollapse = true;
  36.     
  37.     //自定义表格参数
  38.     this.hasPage = true;                            // 是否需要分页工具栏,默认为true
  39.     this.pageSize = Ext.parameter.pageSize;// 分页大小
  40.     this.pagePlace = 'bbar';                        // 分页工具栏位置
  41.     this.hasChkBox = true;                      // 是否支持行复选框,默认为true
  42.     this.hasRowNum = true;                  // 是否支持行自编号,默认为true
  43.     this.metaMode = 'Json';
  44.     
  45.     //自定义数据参数
  46.     this.readMode = 'Json';             //数据加载模式
  47.     this.keyFild = '';                          // 关键字
  48.     this.dataUrl = '';                      // 获取数据的URL
  49.     this.totalProperty = 'totalProperty';
  50.     this.root = 'rootList';
  51.     this.metaFields = undefined;
  52.     
  53.     //自定义排序参数
  54.     this.sort = true;                       //是否支持排序
  55.     this.defaultSort = '';                  // 默认排序字段
  56.     this.defaultDir = 'DESC';           // 默认排序方式
  57.     
  58.     //自定义分组参数
  59.     this.group = false;                 //是否支持分组
  60.     this.groupField = '';                   //默认分组字段
  61.     
  62.     for (var key in config) {
  63.         //将前台的创建参数追个进行加载
  64.         eval("this." + key + " = config." + key + ";");
  65.     }
  66.     Ext.grid.DynamicEditorGridPanel.superclass.constructor.call(thisthis.renderTo,config);
  67. };
  68. /**
  69.  * 动态创建表格实现
  70.  */
  71. Ext.extend(Ext.grid.DynamicEditorGridPanel, Ext.grid.EditorGridPanel, {
  72.     /**
  73.      * 初始化函数
  74.      */
  75.     initComponent : function() {
  76.         
  77.         //加载数据
  78.         this.initStore();
  79.         //是否支持复选列和自编号列
  80.         __hasChkBox = this.hasChkBox;
  81.         __hasRowNum = this.hasRowNum;
  82.         //加入复选列模式
  83.         if(__hasChkBox){
  84.             this.selModel = __chkbox;   
  85.         }
  86.         //为查询框加入数据集
  87.         this.initSearch();
  88.         
  89.         Ext.grid.DynamicEditorGridPanel.superclass.initComponent.call(this);
  90.     },
  91.     /**
  92.      * 重写render函数
  93.      * 创建一个空列
  94.      * 创建数据装载事件
  95.      */
  96.     render : function() {
  97.         //创建空列模型
  98.         this.colModel = new Ext.grid.DefaultColumnModel( [ {
  99.             header :"",
  100.             dataIndex :""
  101.         } ]);
  102.         //创建数据加载时的事件
  103.         this.store.addListener("load"this.doReconfiguration, this);
  104.         //实现
  105.         Ext.grid.DynamicEditorGridPanel.superclass.render.call(this);
  106.     },
  107.     /**
  108.      * 调用动态创建列函数并将列加入表格view
  109.      * 删除store的load装载事件
  110.      */
  111.     doReconfiguration : function() {
  112.         var fields;
  113.         if(this.metaMode === 'Json'){
  114.             fields = this.store.reader.recordType.prototype.fields;
  115.         }else if(this.metaMode === 'Array'){
  116.             fields = this.metaFields;
  117.         }
  118.         this.colModel = new Ext.grid.DynamicColumnModel(this.store,fields,this.metaMode);
  119.         this.view.bindColumnModel(this.colModel);
  120.         this.view.refresh(true);
  121.         this.colModel.defaultSortable = true;
  122.         this.store.removeListener("load"this.doReconfiguration);
  123.     },
  124.     /**
  125.      * 数据加载
  126.      */
  127.     initStore : function() {
  128.         
  129.         var     myUrl = this.dataUrl,
  130.                 myField = this.defaultSort === '' ? this.keyFild : this.defaultSort,
  131.                 myDirection = this.defaultDir,
  132.                 myTotalProperty = this.totalProperty === '' ? 'totalProperty' : this.totalProperty,
  133.                 myRoot = this.root === '' ? 'rootList' : this.root,
  134.                 myPruneModifiedRecords = this.pruneModifiedRecords === true ? true : false;
  135.         // 数据读取器用JSON方式读取数据
  136.         var myReader; 
  137.         
  138.         switch (this.readMode) {
  139.             case 'Json':
  140.                 // 加载Json数据模式
  141.                 myReader = new Ext.data.DynamicJsonReader( {totalProperty :myTotalProperty,root :myRoot});
  142.                 break;
  143.             case 'Xml':
  144.                 // 加载Xml数据模式,待扩展
  145.                 break;
  146.             default:
  147.                 break;
  148.         }
  149.         
  150.         //pruneModifiedRecords 每次进行remove和load时清除modified记录,避免下次提交会把脏modified记录提交
  151.         var myDs =  new Ext.data.Store( {url :myUrl,reader :myReader,pruneModifiedRecords: myPruneModifiedRecords});
  152.         
  153.         if(this.sort){
  154.             //加载排序参数
  155.             myDs.sortInfo = {field :myField,direction :myDirection};            //关键所在,要将排序字段赋给reader以备刷新所用
  156.             myDs.remoteSort = true;
  157.         }
  158.         
  159.         if(this.hasPage){
  160.             var myLimit = this.pageSize;
  161.              // 加载分页数据
  162.             myDs.load( {
  163.                 params : {
  164.                     start :0,
  165.                     limit :myLimit
  166.                 }
  167.             });
  168.             //创建分页栏
  169.             this.initPaging(myDs,myLimit);
  170.         }else{
  171.             // 加载全部数据
  172.             myDs.load();
  173.         }
  174.         this.store = myDs;
  175.     },
  176.     /**
  177.      * 为查询框加入数据集
  178.      * 因为在前台加载grid的时候还没有创建store
  179.      * 所以在本函数加载Ext.app.SearchField的数据store
  180.      */
  181.     initSearch :function() {
  182.         var myStore = this.store;
  183.         for(var i = 0;i < this.tbar.length; i++){
  184.             if (this.tbar[i]  instanceof Ext.app.SearchField){//判断本按钮是否为Ext.app.SearchField的实例如果为实例则为其加入数据
  185.                 var btn = this.tbar[i];
  186.                 btn.store = myStore;
  187.                 break;
  188.             }
  189.         }
  190.     },
  191.     /**
  192.      * 加载分页
  193.      */
  194.     initPaging : function(myStore,myPageSize) {
  195.         //判断是否需要创建分页栏
  196.         var myBBar = new Ext.PagingToolbar( {
  197.             pageSize :myPageSize, // 分页数
  198.             store :myStore, // 填充数据
  199.             displayInfo :true// 是否显示文字信息
  200.             displayMsg :'显示第 {0} 条到 {1} 条记录,一共 {2} 条'// 格式化文字信息
  201.             emptyMsg :"没有数据记录..." // 没有数据时的提示
  202.         });
  203.         
  204.         if(this.pagePlace === 'tbarANDbbar'){
  205.             this.tbar = myBBar; // 加入顶部分页栏
  206.             this.bbar = myBBar; // 加入底部分页栏
  207.         }else if(this.pagePlace === 'tbar'){
  208.             this.tbar = myBBar; // 加入顶部分页栏
  209.         }else{
  210.             this.bbar = myBBar; // 加入底部分页栏
  211.         }
  212.     },
  213.     /**
  214.      * 
  215.      */
  216.     getRecordType : function(){
  217.         return this.store.reader.recordType;
  218.     },
  219.     /**
  220.      * 取修改的起始列数
  221.      */
  222.     getStartEditColNum : function(){
  223.         var num = 0;
  224.         num = this.hasChkBox === true ? num + 1 : num;
  225.         num = this.hasRowNum === true ? num + 1 : num;
  226.         return num;
  227.     }
  228. });
  229. /**
  230.  * 重构JsonReader
  231.  * @param config
  232.  */
  233. Ext.data.DynamicJsonReader = function (config) {
  234.     Ext.data.DynamicJsonReader.superclass.constructor.call(this, config); 
  235. }; 
  236. Ext.extend(Ext.data.DynamicJsonReader, Ext.data.JsonReader, {
  237.     readRecords:function (o) {
  238.     
  239.         for(var key in this.meta){
  240.             if(eval('o.metaData.'+key) === undefined){
  241.                 eval("o.metaData." + key + " = this.meta." + key + ";");
  242.             }
  243.         }
  244.         
  245.         return Ext.data.DynamicJsonReader.superclass.readRecords.call(this, o); 
  246.     }
  247. }); 
  248.     
  249. /**
  250.  * 动态创建表格列
  251.  * @param store
  252.  */
  253. Ext.grid.DynamicColumnModel = function(store,fields,metaMode) {
  254.     var cols = [];
  255.     var recordType = store.reader.recordType;
  256.     // 添加自动编号列
  257.     if (__hasRowNum) {
  258.         var __rownum = new Ext.grid.RowNumberer({});
  259.         cols[cols.length] = __rownum;
  260.     }
  261.     
  262.     // 添加复选列
  263.     if (__hasChkBox) {
  264.         cols[cols.length] = __chkbox;
  265.     }
  266.     if(metaMode === 'Json'){
  267.         for ( var j = 0; j < fields.keys.length; j++) {
  268.             var fieldName = fields.keys[j];
  269.             var field = recordType.getField(fieldName);
  270.             createCols(field);
  271.         }
  272.     }else if(metaMode === 'Array'){
  273.         for ( var k = 0; k < fields.length; k++) {
  274.             createCols(fields[k]);
  275.         }
  276.     }
  277.     /**
  278.      * 创建列数组
  279.      * @param field
  280.      * @return  
  281.      */
  282.     function createCols(field){
  283.         if(field.create === undefined || field.create === true){//默认和true时创建列
  284.             var colsLength = cols.length;
  285.             cols[colsLength] = {//
  286.                 id :field.name, //String主要用于样式选择,如果已定义此属性,那么列所在的单元格会定义class为 x-grid-td-id
  287.                 header :field.header, //String        头部显示的名称
  288.                 dataIndex :field.name, //String        要绑定的Store之Record字段名
  289.                 align :(field.align === undefined || field.align === '' || field.align === null) ? (field.type == ('int' || 'float') ? 'right' : 'left') : field.align, //String        css中的对齐方式
  290.                 width :(field.width === undefined || field.width <=0 || field.width === null) ? undefined : field.width, //宽度
  291.                 sortable :(field.sortable === undefined || field.sortable === true || field.sortable === null) ? true : false,//可排序
  292.                 hidden :(field.hidden === undefined || field.hidden === false || field.hidden === null) ? false : true,//列是否隐藏
  293.                 renderer :(field.renderer === undefined || field.renderer === '' || field.renderer === null) ? undefined : field.renderer,//事件
  294.                 editor :(field.editor === undefined || field.editor === '' || field.editor === null) ? undefined : eval('Ext.util.Editor.'+field.editor+'Editor')
  295.             };
  296.         }
  297.     }
  298.     store.fields = store.reader.recordType.prototype.fields;
  299.     Ext.grid.DynamicColumnModel.superclass.constructor.call(this, cols);
  300. };
  301. /**
  302.  * 动态创建表格列实现
  303.  */
  304. Ext.extend(Ext.grid.DynamicColumnModel, Ext.grid.ColumnModel, {});
  305. /**
  306.  * 绑定列事件
  307.  * @param cm
  308.  * @return
  309.  */
  310. Ext.grid.GridView.prototype.bindColumnModel = function(cm) {
  311.     if (this.cm) {  
  312.         this.cm.un("configchange"this.onColConfigChange, this);
  313.         this.cm.un("widthchange"this.onColWidthChange, this);
  314.         this.cm.un("headerchange"this.onHeaderChange, this);
  315.         this.cm.un("hiddenchange"this.onHiddenChange, this);
  316.         this.cm.un("columnmoved"this.onColumnMove, this);
  317.         this.cm.un("columnlockchange"this.onColumnLock, this);
  318.     }
  319.     if (cm) {
  320.         delete this.lastViewWidth;
  321.         cm.on("configchange"this.onColConfigChange, this);
  322.         cm.on("widthchange"this.onColWidthChange, this);
  323.         cm.on("headerchange"this.onHeaderChange, this);
  324.         cm.on("hiddenchange"this.onHiddenChange, this);
  325.         cm.on("columnmoved"this.onColumnMove, this);
  326.         cm.on("columnlockchange"this.onColumnLock, this);
  327.     }
  328.     this.cm = cm;
  329. };

        该Dynamic Grid中实现了Json和Array两种形式动态创建表格(XML形式大家可以参考论坛上的例子)。

        先来介绍Array的实现方式:

  1.  var fields = [
  2.               {"create":false,"header":" 系统角色编号","name":"roleId",type:"int"}, 
  3.               {"header":" 系统角色名称","name":"roleName"
  4.               {"header":" 是否启用","name":"roleIsforbid"}, 
  5.               {"header":" 备注","name":"mem"
  6.           ];

  7.   var grid = new Ext.grid.DynamicEditorGridPanel( {
          renderTo :'divGrid',
          keyFild :'roleId',//主键ID
          dataUrl :webPath + '/role!ByList.action',//后台取JSON数据的地址
  8.       pruneModifiedRecords : true,
          metaFields : fields,//事先定义的数组
          metaMode :'Array'//动态创建表格的模式为'Array'模式
     });
     grid.render();

        再来介绍Json的实现方式:

  1.     var grid = new Ext.grid.DynamicEditorGridPanel( {
  2.         renderTo :'divGrid',
  3.         keyFild :'roleId',
  4.         dataUrl :webPath + '/role!ByList.action'
  5.     });
  6.     grid.render();

        在这里时应用了JsonReade里面的meta这个属性,所以后台一定要返回如下的数据格式:

  

  1. {"metaData":{"fields":[{"header":"***","name":"**","type":"**"},{"header":"***","name":"**","type":"**"}……]},
  2. "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联系我。

        我会尽快完善代码。并上传实例和源码。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值