http://www.fengfly.com/plus/view-212775-2.html
用户在操作列表的时候,往往会根据自己的使用习惯或者屏幕分辨率来对列的宽度,列的先后顺序,列的可见情况等进行一些调节,这些功能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添加两个属性
- var grid = Ext.create('Ext.grid.Panel', {
- //..
- stateful: true,
- stateId: 'UserList-Grid',
- //...
- });
<2> 编写一个能够和服务器端交互的httpProvider来支持Ext.state.Manager。此处代码也借鉴了很多网络资源,如有雷同纯属巧合。
- Ext.define('Ext.state.HttpProvider',
- {
- extend: 'Ext.state.Provider',
- //构造函数
- constructor : function(config) {
- config = config || {};
- var me = this;
- Ext.apply(me, config);
- this.superclass.constructor.call(this);
- this.state = this.readValues();
- },
- //缓存地址
- url:'',
- // private
- set: function(name, value) {
- if (typeof value == "undefined" || value === null) {
- this.clear(name);
- return;
- }
- if (this.state[name] != value) {
- this.setValue(name, value);
- }
- this.superclass.set.call(this, name, value);
- },
- // 清空数据
- clear: function(name) {
- this.clearValue(name);
- this.superclass.clear.call(this, name);
- },
- // 读取指定用户的全部布局数据
- readValues: function() {
- var state = {};
- var me = this;
- Ext.Ajax.request({
- url: this.url + '/ReadLayout',
- async: false,
- params: {},
- success: function(res, opts) {
- if (res.responseText) {
- var json = Ext.decode(res.responseText);
- if (json && json.length > 0) {
- for (var i = 0; i < json.length; i++) {
- if (json[i].Bustype != "") {
- state[json[i].Bustype] = me.decodeValue(json[i].Value);
- }
- }
- }
- }
- }
- });
- return state;
- },
- // 保存数据
- setValue: function(name, value) {
- var me = this;
- Ext.Ajax.request({
- url: this.url + '/SaveLayout',
- params: {bustype:name,layoutValue:me.encodeValue(value)},
- success: function(res, opts) {
- }
- });
- },
- // 清空数据
- clearValue: function(name) {
- Ext.Ajax.request({
- url: this.url + '/ClearLayout',
- params: {bustype:name},
- success: function(res, opts) {
- }
- });
- }
- });
当然在合适的位置必须加上provider的注册代码:
- Ext.state.Manager.setProvider(new Ext.state.HttpProvider({ url:'你的服务地址' }));
<3> 服务器端方法
1.添加实体对缓存数据进行描述
- /// <summary>
- /// <para>pm_layoutlogInfo Object</para>
- /// <para>Summary description for pm_layoutlogInfo.</para>
- /// <remarks></remarks>
- /// </summary>
- [Serializable]
- public class LayoutLogInfo
- {
- /// <summary>
- /// Gid
- /// </summary>
- public string Gid
- {
- get;
- set;
- }
- /// <summary>
- /// Bustype
- /// </summary>
- public string Bustype
- {
- get;
- set;
- }
- /// <summary>
- /// Logid
- /// </summary>
- public string Logid
- {
- get;
- set;
- }
- /// <summary>
- /// Value
- /// </summary>
- public string Value
- {
- get;
- set;
- }
- }
2.介于本人服务器端为asp.net mvc4 就简单的列一下方法。
- /// <summary>
- /// 获取指定业务布局记忆数据
- /// </summary>
- /// <returns></returns>
- public JsonResult ReadLayout()
- {
- List<LayoutLogInfo> layoutLogInfo = new List<LayoutLogInfo>();
- //...后台获取数据
- return Json(layoutLogInfo, JsonRequestBehavior.AllowGet);
- }
- /// <summary>
- /// 保存布局
- /// </summary>
- /// <param name="bustype"></param>
- /// <param name="layoutValue"></param>
- /// <returns></returns>
- [ActionAuthorize(CtrType.NoThing)]
- public JsonResult SaveLayout(string bustype, string layoutValue)
- {
- ReturnInfo info = new ReturnInfo(true, "");
- //保存实体数据
- return Json(info, JsonRequestBehavior.AllowGet);
- }
- /// <summary>
- ///
- /// </summary>
- /// <param name="bustype"></param>
- /// <returns></returns>
- public JsonResult ClearLayout(string bustype)
- {
- ReturnInfo info = new ReturnInfo(true, "");
- //..清空数据
- return Json(info, JsonRequestBehavior.AllowGet);
- }
<4> 其他注意项:清空状态信息
因为extjs没有提供清空状态的操作,所以如果业务场景需要恢复到默认的状态,就需要在grid的列下拉菜单添加按钮用于向服务端发请求清空数据。以下代码仅简单实现该功能:
- grid.addListener('afterrender', function () {
- if (grid.stateful && grid.stateId != undefined) {
- var menu = this.headerCt.getMenu();
- menu.add([{
- text: '默认布局',
- iconCls: 'icon-Clear',
- handler: function () {
- Ext.state.Manager.clear(grid.stateId);
- window.location.reload();
- }
- }]);
- }
- });
此处我用刷新页面来恢复状态,其实最好的办法还是重绘Grid而不影响其他控件,这里没有展开,也希望有好办法的给我提供下方法。