ExtJs懒人笔记(3) 动态Grid的实现
ExtJs学习目录
引言
使用过.NET 服务端控件的童鞋都应该会对它的方便性记忆犹新,像GridView的使用是非常普遍的,它的好处我就不在多说了。GridVew控件是极其强大的,
我这里只想强调它的一个常见功能——动态列。我们唯一要做的就是为它绑定数据,而不用关心列数的变化,一切都是自适应的。
缘由
最近在使用Extjs制作页面,在使用ExrJs Grid控件时需要实现动态列的效果,也就是列名和数据都是从后台动态获取的。一个简单的功能到了客户端控件,
怎么就这样麻烦呢?在网上查了一番,可能是手气太差,没找到一个较为完整的实例。经过一番研究,自己也琢磨出了一个方法,我想可能是最笨的办法了,
仍然希望和大家分享以便能够得到高人的指点。
原理
对于初学Ext的童鞋来说,以下Grid的使用方法是大家最为熟悉的:
字段设置:
var store = new Ext.data.JsonStore({ fields: [{ name: 'ID', type: 'int' }, { name: 'Name', type: 'string' }, { name: 'En_Name', type: 'string' }, { name: 'HomePage', type: 'string' } ] });
columns: [ { id: 'id', header: 'ID', width: 75, sortable: true, dataIndex: 'ID' }, { header: '姓名', width: 75, sortable: true, dataIndex: 'Name' }, { header: '英文名', width: 75, sortable: true, dataIndex: 'En_Name' }, { header: '网站', width: 250, sortable: true, dataIndex: 'HomePage' }
但是这种写法就限定了字段的数量,而不能做到动态Grid的效果。
但是从ExtJs Grid的使用方法中,我们也能够得到一些启示,如果以上字段和数据信息都从后台获取,问题得以解决 ,但是在真正实施中在构造json数据方面
遇到不少麻烦,特别是后台数据含有\r\n之类就会影响到json,以至前台无法正常显示。
效果
按照规矩,先上图
实例
这里使用了一个插件,DynamicGrid.js
Ext.grid.DynamicGrid = Ext.extend(Ext.grid.GridPanel, { initComponent: function () { //创建store var ds = new Ext.data.Store({ url: this.storeUrl, reader: new Ext.data.JsonReader() }); //设置默认配置 var config = { viewConfig: { forceFit: true }, enableColLock: false, loadMask: true, border: true, stripeRows: true, ds: ds, columns: [] }; //给分页PagingToolbar绑定store this.bbar.bindStore(ds, true); Ext.apply(this, config); Ext.apply(this.initialConfig, config); Ext.grid.DynamicGrid.superclass.initComponent.apply(this, arguments); }, onRender: function (ct, position) { this.colModel.defaultSortable = true; Ext.grid.DynamicGrid.superclass.onRender.call(this, ct, position); this.el.mask('Loading...'); this.store.on('load', function () { if (typeof (this.store.reader.jsonData.columns) === 'object') { var columns = []; if (this.rowNumberer) { columns.push(new Ext.grid.RowNumberer()); } if (this.checkboxSelModel) { columns.push(new Ext.grid.CheckboxSelectionModel()); } Ext.each(this.store.reader.jsonData.columns, function (column) { columns.push(column); } ); this.getColumnModel().setConfig(columns); } this.el.unmask(); }, this); this.store.load(); } }); Ext.grid.DynamicGrid = Ext.extend(Ext.grid.GridPanel, { initComponent: function () { //创建store var ds = new Ext.data.Store({ url: this.storeUrl, reader: new Ext.data.JsonReader() }); //设置默认配置 var config = { viewConfig: { forceFit: true }, enableColLock: false, loadMask: true, border: true, stripeRows: true, ds: ds, columns: [] }; //给分页PagingToolbar绑定store this.bbar.bindStore(ds, true); Ext.apply(this, config); Ext.apply(this.initialConfig, config); Ext.grid.DynamicGrid.superclass.initComponent.apply(this, arguments); }, onRender: function (ct, position) { this.colModel.defaultSortable = true; Ext.grid.DynamicGrid.superclass.onRender.call(this, ct, position); this.el.mask('Loading...'); this.store.on('load', function () { if (typeof (this.store.reader.jsonData.columns) === 'object') { var columns = []; if (this.rowNumberer) { columns.push(new Ext.grid.RowNumberer()); } if (this.checkboxSelModel) { columns.push(new Ext.grid.CheckboxSelectionModel()); } Ext.each(this.store.reader.jsonData.columns, function (column) { columns.push(column); } ); this.getColumnModel().setConfig(columns); } this.el.unmask(); }, this); this.store.load(); } });
页面(View)
<head runat="server"> <title>ExtJs动态Grid实例</title> <link rel="stylesheet" type="text/css" href="http://www.cnblogs.com/Content/ext-3.4.0/resources/css/ext-all.css" /> <script type="text/javascript" src="http://www.cnblogs.com/Content/ext-3.4.0/adapter/ext/ext-base.js"></script> <script src="http://www.cnblogs.com/Content/ext-3.4.0/ext-all.js" type="text/javascript"></script> <script src="http://www.cnblogs.com/Scripts/Widget/DynamicGrid1.js" type="text/javascript"></script> <script language="javascript" type="text/javascript"> Ext.onReady(function () { var dynamicGrid = new Ext.grid.DynamicGrid({ title: '测试动态列', renderTo: 'dynamic-grid', storeUrl: '/DyGrid/GetJson1', width: 600, height: 200, rowNumberer: true, checkboxSelModel: true, sm: new Ext.grid.CheckboxSelectionModel(), bbar: new Ext.PagingToolbar({ pageSize: 5, displayInfo: true, displayMsg: '显示第{0}到{1}条数据,共{2}条', emptyMsg: "没有数据", beforePageText: "第", afterPageText: '页 共{0}页' }) }); }) </script> </head> <body> <div id="dynamic-grid"> </div> </body>
Controller:
/// <summary> /// 构造动态grid的数据 /// </summary> /// <returns></returns> public string GetJson1() { string strGridData = ""; //1.构造Grid字段 List<string> lstColumns = new List<string>(); lstColumns.Add("id"); lstColumns.Add("name"); string Coloumns = ""; Coloumns += "["; for (int i = 0; i < lstColumns.Count;i++ ) { Coloumns += "{\"name\":\"" + lstColumns[i] + "\"},"; } Coloumns = Coloumns.Remove(Coloumns.LastIndexOf(','));//注意去掉最后一个多余的逗号 Coloumns += "]"; //2.构造Grid数据 string strResult = ""; strResult += "["; for (int i = 0; i < 10; i++) { //strResult += "[\"" + i + "\",\"" + i + "\",\"" + i + "\",\"" + i + "\"],"; strResult += "{\"id\":\"" + i + "\",\"name\":\"" + i + "\"},"; } strResult = strResult.Remove(strResult.LastIndexOf(','));//注意去掉最后一个多余的逗号 strResult += "]"; //3.构造header列名 //List<string> lstHeaders = new List<string>(); string strHeaders = ""; strHeaders = "["; for (int j = 0; j < lstColumns.Count;j++ ) { strHeaders += "{\"header\":\"" + lstColumns[j] + "\",\"dataIndex\":\"" + lstColumns[j] + "\"},"; } strHeaders = strHeaders.Remove(strHeaders.LastIndexOf(','));//注意去掉最后一个多余的逗号 strHeaders += "]"; //4 strGridData = "{ "; strGridData += "'metaData': {'totalProperty': 'total','root': 'records','id': 'id','fields':"+Coloumns+"}"; strGridData += ","; strGridData += "'success': true,"; strGridData += " 'total': 50,"; strGridData += " 'records': "+strResult+","; strGridData += "'columns':" + strHeaders + ""; strGridData += "} "; return strGridData; }
以上源码均有较为详尽的注释,不再说明。
交流
由于这里只是一个实例,实际的项目无法带出公司,但是项目中后台数据来自excel导入的到mongdb数据库,获取到的字符串中含有换行之类的,
影响了构成json,导致了Grid的无法正常呈现数据,同时,由于mongdb的一个集合中都可以存储不同的字段数目。这就导致此种方案失效,
有没有一种更加成熟和通用的方案呢?
转载请注明出处:http://www.cnblogs.com/lucky_hu/archive/2012/07/15/2591995.html