惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Blog — PlanetScale
Blog — PlanetScale
B
Blog
A
About on SuperTechFans
大猫的无限游戏
大猫的无限游戏
爱范儿
爱范儿
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
H
Help Net Security
H
Hackread – Cybersecurity News, Data Breaches, AI and More
博客园 - 三生石上(FineUI控件)
有赞技术团队
有赞技术团队
酷 壳 – CoolShell
酷 壳 – CoolShell
WordPress大学
WordPress大学
IT之家
IT之家
D
Docker
Google DeepMind News
Google DeepMind News
罗磊的独立博客
T
The Blog of Author Tim Ferriss
aimingoo的专栏
aimingoo的专栏
博客园 - 叶小钗
Recent Announcements
Recent Announcements
阮一峰的网络日志
阮一峰的网络日志
D
DataBreaches.Net
博客园 - 司徒正美
Engineering at Meta
Engineering at Meta

博客园 - 冬冬

高校、科研院所科研信息管理系统 - 寻求合作 走向管理之路:从向别人求助开始 C语言数据结构学习用单元测试 人性与天性 提问的方式方法 使用ExtJs开发MIS系统(系列文章) 使用ExtJs开发MIS系统(7):ExtJs性能浅析 使用ExtJs开发MIS系统(6):客户端MVC 使用ExtJs开发MIS系统(5):使用Action抽象客户端操作 使用ExtJs开发MIS系统(4):轮询 使用ExtJs开发MIS系统(2):Js的动态加载 使用ExtJs开发MIS系统(1):基于ExtJs的MIS构架设计 项目管理纵横谈(2)──继续说项目管理的目标 项目管理纵横谈(1)──项目的管理的目标 网路爬虫(3):url索引 权限系统设计 团队管理心得总结--回复别人的邮件 团队职能划分 战略与战术--再论软件设计的度
使用ExtJs开发MIS系统(3):使用数据库保存客户端状态
冬冬 · 2008-12-19 · via 博客园 - 冬冬

我们都知道,Vs.Net这样的工具每次打开时都会记住我们上次关闭时的状态:各个窗口的位置、大小;工具栏状态;自定义菜单项等。这无疑是一个使用的功能。ExtJs也包含提供了状态保存机制,其主要的控件:GirdPanel,FormPanel等,都提供了状态保存的功能。我们需要的仅仅是为其提供适当的Provider。

1,客户端状态的保存

我们先来看一下当一个ExtJs中的控件状态改变时,持久化该控件状态的流程:

image 

流程中的前两步(红色)是控件负责的。当控件状态改变时,会使用JSON串行化自身状态,然后调用Ext.state.Manager.getProvider()这个静态方法取得当前程序配置的Provider,进而调用Provider的set方法,保存自身状态。我们需要做的便是提供一个Provider,当其set方法被调用时,将传递过来的控件状态保存到服务器就可以了。该Provider的代码如下:

   1:  Srims.providerCtor = Ext.extend(Ext.state.Provider, {
   2:   
   3:      get: function(name, defaultValue){
   4:          //alert('get:' + name + ' : ' + Srims.provider._state[name]);
   5:          //return defaultValue;
   6:          
   7:          if (Srims.provider._state[name]) 
   8:              return Ext.util.JSON.decode(Srims.provider._state[name]);
   9:          
  10:          return defaultValue;
  11:      },
  12:      set: function(name, value){
  13:          //alert('set:' + name + ' ' + Ext.util.JSON.encode(value));
  14:          var valueString = Ext.util.JSON.encode(value)
  15:          Srims.provider._state[name] = valueString;
  16:          
  17:          Ext.Ajax.request({
  18:              url: '/User.asmx/SetExtClientState',
  19:              method: 'POST',
  20:              params: {
  21:                  key: name,
  22:                  value: valueString
  23:              }
  24:          });
  25:      },
  26:      clear: function(name){
  27:          Srims.provider._state[name] = undefined;
  28:      }
  29:  });
  30:   
  31:  Srims.provider = new Srims.providerCtor();
  32:  Srims.provider._state = new function(){
  33:  };

其中Srims.privoider._state(32行)是本地用于保存状态的对象,相当于一个缓存。set方法首先编码控件状态(14行),然后将控件状态储存在Srims.privoider._state中(15行),进而发起Ajax请求,调用WebService,传递控件ID及其状态,服务器端将根据这两个参数持久化该控件当前状态(17行)。至此是流程图中的第三、四两步(蓝色表示)。

定义了Provider类后,我们就可以把它构造出来(31行),然后调用:

Ext.state.Manager.setProvider(Srims.provider);

将我们的Provider设置为系统公用的,这样ExtJs中的控件就可以使用Ext.state.Manager.getProvider()得到这个Provider了。

服务器端Users.asmx的SetExtClientState'方法负责保存客户端控件的状态,对应流程中最后两步(绿色表示)。使用XML串行化所有控件的状态,形成的XML类似以下样子:

   1:  <?xml version="1.0" encoding="utf-8"?>
   2:  <ExtClientState>
   3:    
   4:    <ProjectGridPanel_HorizontalList>
   5:      {"columns":[{"id" :0,"hidden":true},{"id":1,"width":93},......
   6:    </ProjectGridPanel_HorizontalList>
   7:    
   8:    <ProjectGridPanel_VerticalList>
   9:      {"columns":[{"id":0,"hidden":true},......
  10:    </ProjectGridPanel_VerticalList>
  11:    
  12:    <DivPanelMenu>
  13:      {"collapsed":false}
  14:    </DivPanelMenu>
  15:    
  16:  </ExtClientState>

其中节点名称是客户端控件的ID,节点的值是该控件的状态。上面的XML描述了三个控件的状态,其中前两个:ProjectGridPanel_HorizontalListProjectGridPanel_VerticalList是GridPanel,最后一个DivPanelMenu是Panel。

2,状态的加载与还原

当下一次系统加载的时候,我们在所有控件加载之前,先把这个XML发送给客户端,就可以复原客户端状态了,代码如下:

   1:  Srims.provider.loadState = function(callback){
   2:      Ext.Ajax.request({
   3:          url: '/User.asmx/GetExtClientState',
   4:          method: 'POST',
   5:          success: Srims.provider._onLoadState,
   6:          scope: callback
   7:      });
   8:  };
   9:  Srims.provider._onLoadState = function(response){
  10:   
  11:      var rootNode = Ext.DomQuery.selectNode('/ExtClientState', response.responseXML);
  12:      var nodes = Ext.DomQuery.select('*', rootNode);
  13:      
  14:      for (var i = 0; i < nodes.length; i++) {
  15:          var node = nodes[i];
  16:          Srims.provider._state[node.tagName] = Ext.DomQuery.selectValue('/', node);
  17:          //alert(node.tagName + Srims.provider._state[node.tagName]);
  18:      }
  19:      
  20:      this();
  21:  }

第二行的Ajax请求负责从User.asmx/GetExtClientState读客户端状态,其响应是上面的XML。然后回调函数Srims.provider._onLoadState负责将状态解析还原到Srims.provider._state这个本地缓存中。

客户端状态还原后,控件加载的时候,就可以使用Provider提取上次的状态。状态的加载和恢复的流程总结如下:

image 

本文中出现的代码,去掉注释后结合FireBug可以清楚地了解到整个状态保存和还原的过程。