您的位置:首页 > 数据库

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

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

1,客户端状态的保存

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





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

Srims.providerCtor=Ext.extend(Ext.state.Provider,{
[code]
get:function(name,defaultValue){
//alert('get:'+name+':'+Srims.provider._state[name]);
//returndefaultValue;
if(Srims.provider._state[name])
returnExt.util.JSON.decode(Srims.provider._state[name]);
returndefaultValue;
},
set:function(name,value){
//alert('set:'+name+''+Ext.util.JSON.encode(value));
varvalueString=Ext.util.JSON.encode(value)
Srims.provider._state[name]=valueString;
Ext.Ajax.request({
url:'/User.asmx/SetExtClientState',
method:'POST',
params:{
key:name,
value:valueString
}
});
},
clear:function(name){
Srims.provider._state[name]=undefined;
}
});
Srims.provider=newSrims.providerCtor();
Srims.provider._state=newfunction(){
};

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

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

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

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

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

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

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

<?xmlversion="1.0"encoding="utf-8"?>
<ExtClientState>
<ProjectGridPanel_HorizontalList>
{"columns":[{"id":0,"hidden":true},{"id":1,"width":93},......
</ProjectGridPanel_HorizontalList>
<ProjectGridPanel_VerticalList>
{"columns":[{"id":0,"hidden":true},......
</ProjectGridPanel_VerticalList>
<DivPanelMenu>
{"collapsed":false}
</DivPanelMenu>
</ExtClientState>

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

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

2,状态的加载与还原

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

Srims.provider.loadState=function(callback){
Ext.Ajax.request({
url:'/User.asmx/GetExtClientState',
method:'POST',
success:Srims.provider._onLoadState,
scope:callback
});
};
Srims.provider._onLoadState=function(response){
varrootNode=Ext.DomQuery.selectNode('/ExtClientState',response.responseXML);
varnodes=Ext.DomQuery.select('*',rootNode);
for(vari=0;i<nodes.length;i++){
varnode=nodes[i];
Srims.provider._state[node.tagName]=Ext.DomQuery.selectValue('/',node);
//alert(node.tagName+Srims.provider._state[node.tagName]);
}
this();
}

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{margin:0em;}
.csharpcode.rem{color:#008000;}
.csharpcode.kwrd{color:#0000ff;}
.csharpcode.str{color:#006080;}
.csharpcode.op{color:#0000c0;}
.csharpcode.preproc{color:#cc6633;}
.csharpcode.asp{background-color:#ffff00;}
.csharpcode.html{color:#800000;}
.csharpcode.attr{color:#ff0000;}
.csharpcode.alt
{
background-color:#f4f4f4;
width:100%;
margin:0em;
}
.csharpcode.lnum{color:#606060;}

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

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





本文中出现的代码,去掉注释后结合FireBug可以清楚地了解到整个状态保存和还原的过程。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐