使用ExtJs开发MIS系统(3):使用数据库保存客户端状态

简介:

我们都知道,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可以清楚地了解到整个状态保存和还原的过程。

本文转自冬冬博客园博客,原文链接:http://www.cnblogs.com/yuandong/archive/2008/12/19/1358663.html ,如需转载请自行联系原作者
相关文章
|
18天前
|
存储 SQL API
探索后端开发:构建高效API与数据库交互
【10月更文挑战第36天】在数字化时代,后端开发是连接用户界面和数据存储的桥梁。本文深入探讨如何设计高效的API以及如何实现API与数据库之间的无缝交互,确保数据的一致性和高性能。我们将从基础概念出发,逐步深入到实战技巧,为读者提供一个清晰的后端开发路线图。
|
16天前
|
存储 缓存 NoSQL
2款使用.NET开发的数据库系统
2款使用.NET开发的数据库系统
|
19天前
|
存储 SQL 数据库
深入浅出后端开发之数据库优化实战
【10月更文挑战第35天】在软件开发的世界里,数据库性能直接关系到应用的响应速度和用户体验。本文将带你了解如何通过合理的索引设计、查询优化以及恰当的数据存储策略来提升数据库性能。我们将一起探索这些技巧背后的原理,并通过实际案例感受优化带来的显著效果。
36 4
|
28天前
|
存储 Java 关系型数据库
在Java开发中,数据库连接是应用与数据交互的关键环节。本文通过案例分析,深入探讨Java连接池的原理与最佳实践
在Java开发中,数据库连接是应用与数据交互的关键环节。本文通过案例分析,深入探讨Java连接池的原理与最佳实践,包括连接创建、分配、复用和释放等操作,并通过电商应用实例展示了如何选择合适的连接池库(如HikariCP)和配置参数,实现高效、稳定的数据库连接管理。
52 2
|
29天前
|
关系型数据库 MySQL Linux
Linux系统如何设置自启动服务在MySQL数据库启动后执行?
【10月更文挑战第25天】Linux系统如何设置自启动服务在MySQL数据库启动后执行?
74 3
|
28天前
|
Java 数据库连接 数据库
深入探讨Java连接池技术如何通过复用数据库连接、减少连接建立和断开的开销,从而显著提升系统性能
在Java应用开发中,数据库操作常成为性能瓶颈。本文通过问题解答形式,深入探讨Java连接池技术如何通过复用数据库连接、减少连接建立和断开的开销,从而显著提升系统性能。文章介绍了连接池的优势、选择和使用方法,以及优化配置的技巧。
27 1
|
28天前
|
监控 Java 数据库连接
在Java开发中,数据库连接管理是关键问题之一
在Java开发中,数据库连接管理是关键问题之一。本文介绍了连接池技术如何通过预创建和管理数据库连接,提高数据库操作的性能和稳定性,减少资源消耗,并简化连接管理。通过示例代码展示了HikariCP连接池的实际应用。
20 1
|
2月前
|
SQL JavaScript 关系型数据库
node博客小项目:接口开发、连接mysql数据库
【10月更文挑战第14天】node博客小项目:接口开发、连接mysql数据库
|
2月前
|
SQL 存储 关系型数据库
数据储存数据库管理系统(DBMS)
【10月更文挑战第11天】
105 3
|
2月前
|
运维 NoSQL BI
简道云搭载阿里云MongoDB数据库,帮助数以万计企业重构业务系统
通过与MongoDB和阿里云团队的合作,让简道云少走了弯路,保障了线上服务的长期稳定运行,提高了吞吐效率,并相应降低了线上运行成本