首页 > 代码库 > ExtJS4.2 仅需配置URL动态加载GridPanel列(带分页)

ExtJS4.2 仅需配置URL动态加载GridPanel列(带分页)

最近做ExtJS一直想做个傻瓜式的GridPanel,今天折腾了一天,从GitHub找到的老外写的解决方案, 在他的基础上做了一些改动,增加了分页,增加了columns手动配置(原本只能动态生成),大家有兴趣可以自由扩展,我做了很详细的注释

 

效果图如下,仅需在html页面引入ext.all,并创建自定义控件,配置url即可创建带分页效果的GirdPanel

代码:

效果图:

 

一、动态加载自定义控件

自定义脚本包括两部分:DynamicGrid.js和DynamicReader.js

将Ext目录放到Web根目录下,两个文件的路径分别放在如下路径

Ext/src/ux/grid/DynamicGrid.js

Ext/src/ux/data/reader/DynamicReader.js

严格按照这个目录来放可以避免配置动态加载的路径

 

二、DynamicGrid.js 文件

 

定义了基本的配置项,如果调用时已配置,不会再次配置。

核心部分是监听metachange事件调用reconfigure方法,实现动态加载列。

 

 1 /** 2  * Lukas Sliwinski 3  * sliwinski.lukas@gmail.com 4  * Dynamic grid, allow to display data setting only URL. 5  * Columns and model will be created dynamically. 6  * 中文注释及修改:龚英韬 holdengong@gmail.com 7  */ 8 Ext.define(‘Ext.ux.grid.DynamicGrid‘, { 9     extend: ‘Ext.grid.Panel‘,10     //widget定义了一系列的string,它存在的意义主要是记录——在实际编码中直接用类似 ‘actioncolumn‘,不要像这样引用: Ext.enums.Widget.actioncolumn.11     alias: ‘widget.dynamicGrid‘,12     alternateClassName: ‘Ext.grid.DynamicGrid‘,13     //加载依赖项;14     requires: [15         ‘Ext.ux.data.reader.DynamicReader‘16     ],17     // 必须配置url从服务端加载数据18     url: ‘‘,19     fields:[],20     initComponent: function () {21         console.log(‘DynamicGrid Init‘);22         var me = this;23 24         if (me.url == ‘‘) {25             Ext.Error.raise(‘url不能为空! 你必须要设置url以从服务器取得数据‘);26         }27         else {28             //applyIf( object, config ) : Object29             //如果该配置项不存在,拷贝到该对象30             Ext.applyIf(me, {31                 columns: [],32                 forceFit: true,33                 store: Ext.create(‘Ext.data.Store‘, {34                     id: "_store_dynamicgrid",35                     // fields必须设置为空的Array. 不然Ext会动态创建一个匿名model.36                     fields: me.fields,37                     pageSize: 10,38                     // 加载数据后,grid会动态重新配置columns39                     // Ext.ux.data.reader.DynamicReader40                     listeners: {41                         //当store底层的reader的元数据改变时触发.元数据通常包括新的字段定义,42                         //但是也可以包含任何配置信息, 此事件目前只能被 JsonReaders触发43                         ‘metachange‘: function (store, meta) {44                             //*龚英韬+*如果没有配置columns,则动态生成columns45                             if (me.columns.length <= 0) {46                                 console.log(me.columns == []);47                                 me.reconfigure(store, meta.columns);48                             }49                         }50                     },51                     autoLoad: true,52                     remoteSort: false,53                     remoteFilter: false,54                     remoteGroup: false,55                     proxy: {56                         reader: ‘dynamicReader‘,57                         type: ‘ajax‘,58                         url: me.url59                     }60                 }),61                 //*龚英韬+*62                 dockedItems: [{63                     xtype: ‘pagingtoolbar‘,64                     store: Ext.StoreManager.lookup("_store_dynamicgrid"),   // same store GridPanel is using65                     dock: ‘bottom‘,66                     displayInfo: true67                 }]68             });69         }70 71         me.callParent(arguments);72     }73 });
View Code

 

三、DynamicReader.js 文件

核心是通过readRecords方法,分析一个record,动态得到columns和fields,触发metachange事件,然后Grid会调用reconfigure

 

 

 1 /** 2  * @class Ext.ux.data.DynamicReader 3  * @extends Ext.data.reader.Json 4  * <p>Dynamic reader, allow to get working grid with auto generated columns and without setting a model in store</p> 5  * 中文注释及修改:龚英韬 holdengong@gmail.com 6  */ 7  8 /** 9  * floatOrString 数据类型帮助更准确的排序10  */11 Ext.Loader.setConfig({ enabled: true });12 Ext.Loader.setPath("Ext.ux", ".");13 Ext.apply(Ext.data.Types, {14     FLOATORSTRING: {15         convert: function(v, n) {16             v = Ext.isNumeric(v) ? Number(v) : v;17             return v;18         },19         sortType: function(v) {20             v = Ext.isNumeric(v) ? Number(v) : v;21             return v;22         },23         type: ‘floatOrString‘24     }25 });26 27 Ext.define(‘Ext.ux.data.reader.DynamicReader‘, {28     extend: ‘Ext.data.reader.Json‘,29     alias: ‘reader.dynamicReader‘,30     alternateClassName: ‘Ext.data.reader.DynamicReader‘,31     type: "json",32     root: "rows",33     totalProperty: "total",34     //读取JSON数据并返回结果集.用内部的getTotal和getSuccess方法从返回数据中提取元数据,并将提取的数据转换为model.35     readRecords: function (data) {36         //如果data不为空37         if (data) {38             //取到data的rows的第一个model39             var item = data.rows[0];40             var fields = new Array();41             var columns = new Array();42             var p;43 44             for (p in item) {45                 if (p && p != undefined) {46                     // floatOrString 类型只是一种选项47                     // 你可以新建自己的类型应对更复杂的情况48                     // 或者干脆设置为‘string‘49                     fields.push({ name: p, type: ‘floatOrString‘ });50                     columns.push({ text: p, dataIndex: p });51                 }52             }53 54             data.metaData =http://www.mamicode.com/ { fields: fields, columns: columns };55         }56         //调用当前方法的父方法.57         return this.callParent([data]);58     }59 });
View Code

 

 

四、后台代码

因为实现了分页,返回给前台的JSON格式应该是 {"total":total,"rows":[{"attr":"value"},{"attr":"value"}]}

我是用.NET MVC写的

 

1 public string Read(int limit, int start)2         {3             var logs= LoginLog.GetLoginLogs().OrderByDescending(l => l.loginTime).Skip(start).Take(limit);4             string total = LoginLog.GetLoginLogs().Count.ToString();5             string json = logs.ToJson();6             string res = "{\"total\":" + total + ",\"rows\":" + json + "}";7             return res;8         }