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  * [email protected]

 4  * Dynamic grid, allow to display data setting only URL.

 5  * Columns and model will be created dynamically.

 6  * 中文注释及修改:龚英韬 [email protected]

 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 ) : Object

29             //如果该配置项不存在,拷贝到该对象

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会动态重新配置columns

39                     // Ext.ux.data.reader.DynamicReader

40                     listeners: {

41                         //当store底层的reader的元数据改变时触发.元数据通常包括新的字段定义,

42                         //但是也可以包含任何配置信息, 此事件目前只能被 JsonReaders触发

43                         'metachange': function (store, meta) {

44                             //*龚英韬+*如果没有配置columns,则动态生成columns

45                             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.url

59                     }

60                 }),

61                 //*龚英韬+*

62                 dockedItems: [{

63                     xtype: 'pagingtoolbar',

64                     store: Ext.StoreManager.lookup("_store_dynamicgrid"),   // same store GridPanel is using

65                     dock: 'bottom',

66                     displayInfo: true

67                 }]

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  * 中文注释及修改:龚英韬 [email protected]

 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的第一个model

39             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 = { 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         }

 

 

你可能感兴趣的:(gridPanel)