Extjs-GridPanel列状态记忆功能实现
用户在操作列表的时候,往往会根据自己的使用习惯或者屏幕分辨率来对列的宽度,列的先后顺序,列的可见情况等进行一些调节,这些功能Extjs-GridPanel自身已经包含。在这些操作后,用户又往往希望下次再使用该界面的时候能够重现上次的操作结果。这就带出来本文的主题----列状态记忆功能。以下就实现列状态后台记忆功能分几点进行描述说明:
一、Extjs状态管理机制
Extjs4.1提供了一个状态管理器:Ext.state.Manager。查看该类源码可以发现,其引用了Ext.state.Provider类,并且其方法仅:setProvider、getProvider、get、set、clear。可以说真正的状态保存类还是在Ext.state.Provider上。Extjs为我们其实提供了一个Provider:Ext.state.CookieProvider,查看其代码,豁然开朗。无非就是用Cookie对控件的一些状态属性进行了保存和读取。
查看浏览器的cookie记录情况:
可以发现,我们需求做的就是把键值对丢到后台数据库里。而且,很多对控件的设置功能,原生控件已经全部包括,grid里面对于状态的管理真正起作用的可能就是:getState、applyState方法。
二、使用步骤
<1>为gridPanel添加两个属性
1 var grid = Ext.create('Ext.grid.Panel', { 2 //.. 3 stateful: true, 4 stateId: 'UserList-Grid', 5 //... 6 });
<2> 编写一个能够和服务器端交互的httpProvider来支持Ext.state.Manager。此处代码也借鉴了很多网络资源,如有雷同纯属巧合。
1 Ext.define('Ext.state.HttpProvider', 2 { 3 extend: 'Ext.state.Provider', 4 //构造函数 5 constructor : function(config) { 6 config = config || {}; 7 var me = this; 8 Ext.apply(me, config); 9 10 this.superclass.constructor.call(this); 11 this.state = this.readValues(); 12 }, 13 //缓存地址 14 url:'', 15 // private 16 set: function(name, value) { 17 if (typeof value == "undefined" || value === null) { 18 this.clear(name); 19 return; 20 } 21 22 if (this.state[name] != value) { 23 this.setValue(name, value); 24 } 25 26 this.superclass.set.call(this, name, value); 27 }, 28 // 清空数据 29 clear: function(name) { 30 this.clearValue(name); 31 this.superclass.clear.call(this, name); 32 }, 33 // 读取指定用户的全部布局数据 34 readValues: function() { 35 var state = {}; 36 var me = this; 37 Ext.Ajax.request({ 38 url: this.url + '/ReadLayout', 39 async: false, 40 params: {}, 41 success: function(res, opts) { 42 if (res.responseText) { 43 var json = Ext.decode(res.responseText); 44 if (json && json.length > 0) { 45 46 for (var i = 0; i < json.length; i++) { 47 if (json[i].Bustype != "") { 48 state[json[i].Bustype] = me.decodeValue(json[i].Value); 49 } 50 51 } 52 } 53 } 54 } 55 }); 56 57 return state; 58 }, 59 // 保存数据 60 setValue: function(name, value) { 61 var me = this; 62 Ext.Ajax.request({ 63 url: this.url + '/SaveLayout', 64 params: {bustype:name,layoutValue:me.encodeValue(value)}, 65 success: function(res, opts) { 66 } 67 }); 68 }, 69 // 清空数据 70 clearValue: function(name) { 71 Ext.Ajax.request({ 72 url: this.url + '/ClearLayout', 73 params: {bustype:name}, 74 success: function(res, opts) { 75 } 76 }); 77 } 78 });
当然在合适的位置必须加上provider的注册代码:
Ext.state.Manager.setProvider(new Ext.state.HttpProvider({ url:'你的服务地址' }));
<3> 服务器端方法
1.添加实体对缓存数据进行描述
1 /// <summary> 2 /// <para>pm_layoutlogInfo Object</para> 3 /// <para>Summary description for pm_layoutlogInfo.</para> 4 /// <remarks></remarks> 5 /// </summary> 6 [Serializable] 7 public class LayoutLogInfo 8 { 9 /// <summary> 10 /// Gid 11 /// </summary> 12 public string Gid 13 { 14 get; 15 set; 16 } 17 18 /// <summary> 19 /// Bustype 20 /// </summary> 21 public string Bustype 22 { 23 get; 24 set; 25 } 26 27 /// <summary> 28 /// Logid 29 /// </summary> 30 public string Logid 31 { 32 get; 33 set; 34 } 35 36 /// <summary> 37 /// Value 38 /// </summary> 39 public string Value 40 { 41 get; 42 set; 43 } 44 }
2.介于本人服务器端为asp.net mvc4 就简单的列一下方法。
1 /// <summary> 2 /// 获取指定业务布局记忆数据 3 /// </summary> 4 /// <returns></returns> 5 public JsonResult ReadLayout() 6 { 7 List<LayoutLogInfo> layoutLogInfo = new List<LayoutLogInfo>(); 8 9 //...后台获取数据 10 11 return Json(layoutLogInfo, JsonRequestBehavior.AllowGet); 12 } 13 /// <summary> 14 /// 保存布局 15 /// </summary> 16 /// <param name="bustype"></param> 17 /// <param name="layoutValue"></param> 18 /// <returns></returns> 19 [ActionAuthorize(CtrType.NoThing)] 20 public JsonResult SaveLayout(string bustype, string layoutValue) 21 { 22 ReturnInfo info = new ReturnInfo(true, ""); 23 24 //保存实体数据 25 26 return Json(info, JsonRequestBehavior.AllowGet); 27 } 28 /// <summary> 29 /// 30 /// </summary> 31 /// <param name="bustype"></param> 32 /// <returns></returns> 33 public JsonResult ClearLayout(string bustype) 34 { 35 ReturnInfo info = new ReturnInfo(true, ""); 36 37 //..清空数据 38 39 return Json(info, JsonRequestBehavior.AllowGet); 40 41 }
<4> 其他注意项:清空状态信息
因为extjs没有提供清空状态的操作,所以如果业务场景需要恢复到默认的状态,就需要在grid的列下拉菜单添加按钮用于向服务端发请求清空数据。以下代码仅简单实现该功能:
1 grid.addListener('afterrender', function () { 2 3 if (grid.stateful && grid.stateId != undefined) { 4 var menu = this.headerCt.getMenu(); 5 6 menu.add([{ 7 text: '默认布局', 8 iconCls: 'icon-Clear', 9 handler: function () { 10 Ext.state.Manager.clear(grid.stateId); 11 window.location.reload(); 12 } 13 }]); 14 15 } 16 17 });
此处我用刷新页面来恢复状态,其实最好的办法还是重绘Grid而不影响其他控件,这里没有展开,也希望有好办法的给我提供下方法。