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