`

《易道客》源码剖析之四:页面多次跳转的记忆

阅读更多

一、介绍(测试请在3.0.1以上版本)

页面多次跳转之后,还能记忆原页面的状态,是本系统的一大特色。

 

我们以“我的客户”为例,进入客户列表,点击“查询”,弹出过滤条件窗口,在客户类别中选择“线索客户”,过滤后跳转到第3页。然后在列表中间选择一个客户,点击“详述”按钮,进入详述页面,再单击“联系人”右页签,进入该客户的联系人列表,修改一个联系人信息,再增加一个联系人信息。再次回到联系人列表,点击上方的“返回”按钮,返回到“客户列表”。经过了N多次的页面跳转后……

 

此时:你会发现,你仍然停留在第3页,看到的数据仍然是刚才过滤之后的“线索客户”,左侧的单按钮,仍然选中你刚才操作的哪个客户。

 

查看视频演示

 

二、实现原理

1B/S架构中,页面跳转之后,要想返回时还记忆起以前的状态,有两种方式,第一,将该页面中所有的状态数据放入session中,再返回该页面时取出恢复。第二,将状态数据放入表单一并提交至下一个页面,在下一页面返回时,再将这些状态数据提交回来,这样第一个页面也可以读到以前的状态数据并恢复。这种方式下,如果存在多次跳转,每一步跳转,都必须带着状态数据,合理的规划就显得十分重要。本系统采用的是第二种方式。

 

2、在系统中,将状态数据分为三类:查询条件,穿越条件和分页信息。

1)查询条件:如我的客户列表中,当前列表是经过哪些查询条件过滤而得到的,如客户类别、所属区域等,这些条件数据都需要记录下来。以SEARCH_为前缀来区分。

 

2)穿越条件:标识当前列表中选中的是第几条数据,记录的是该条数据的唯一ID。以RELATION_为前缀来区分。

 

3)分页信息:符合查询条件的数据可能有很多,会有很多页,分页信息就是记录下当前的页码信息。只有两个属性:SEARCH_EgecStart(当前页开始记录的编号,就是所有符合查询条件的记录中,当前页面从第几条开始显示)和SEARCH_EgecPerNum(每页显示的条数)

 

3、在一个列表页面中,左侧单选按钮的名称是以RELATION_开头的,在列表页跳转到其他页面时,按钮值直接作为穿越条件带入到下一页面。

 

4、两个机制来保证:requestType(请求类型)和mastKeep(必须保持)

1requestType标识跳转到一个新页面时,哪些状态数据被从请求参数中取出来作为新页面表单的隐藏域。它有五种类型的值:

Aall:取出所有:包含了穿越和查询(含分页信息)

Bre:只取穿越条件(含分页信息)

Cse:只取查询条件(含分页信息)

Dall_no:取出所有:包含了穿越和查询(注:不包含分页参数)

Ese_no:只取查询条件(注:不包含分页参数)

每到一个新页面时,就根据先用getParametergetAttribute中取得requestType的值,再根据requestType的值类型,取相对应的状态数据,将这些状态数据以隐藏域的方式,放在页面表单内,当该页面跳转时,再将这些隐藏域带到下一页面。每次跳转,requestType需要根据不同的需求情况,赋于不同的值。

 

2mastKeep是个字符串数组,代表这些名称的状态数据必须取出来,不受requestType值类型的限制。它通常用于从一个列表跳转别一个列表时,记录下前一个列表的穿越条件。例如:从我的客户详述联系人列表这个过程中,在跳转到联系人列表时,必须记录下当前选中客户的唯一IDRELATION_Client_id),但不必要记录当前选中联系人的唯一IDRELATION_LinkMan_id),因为当前选中联系人的ID是由联系人列表左侧的单选按钮来记录,如果再用隐藏域来记录,就会出现在一个表单内两个重复的元素名称。这种情况下,requestType是不能使用all,re,all_no三个值,因为它们都将列出以RELATION_开头的穿越条件,联系人IDRELATION_LinkMan_id)也将会被取出作为隐藏域,就会在页面表单内出现重复的元素名称(RELATION_LinkMan_id)。此时,可以将客户IDRELATION_Client_id)放mastKeep中,此处的requestType请求参数值用sese_no就可以了。

 

5、两个form表单

addCommon.jsplistCommon.jsp页面,每个页面都有两个form表单,名称分别是form1form2

 

1form1用于正常的数据请求,如:增加页面的提交、列表页面选中某记录时的修改。From1表单的requestType元素值(即该表单向下一页面提交时,requestType传什么值过去)是在展示页面之前的action中设置的。表单的隐藏域(状态数据)有哪些,是由上一页面传进来的requestType请求参数值决定的,根据值的不同,给表单加入不同的隐藏域。见上面对requestType值的解释。

 

2form2表单是个空的隐藏表单,表单元素requestType的值默认是all,在调用js方法form2Submit()提交表单时,会用传进来的参数动态改变它的值。表单的隐藏域(状态数据)是上一表单传过来的所有数据(查询条件、穿越条件、分页信息),不受上一表单传入requestType请求参数值的影响。该表单主要用于“返回”操作,或右页签按钮请求时。

 

三、源码跟踪分析

1、操作路径:

1)我的客户列表

2)查询类别为“线索客户”的客户

3)翻页至第3,选中一条数据“详述”查看

4)点击右页签“联系人”,进入联系人列表

5)选中一个联系人,并点击“修改”

6)提交修改结果

7)显示成功信息

8)返回联系人列表,点击上方“返回”按钮

9)返回客户列表,我们会发现,还是刚才的查询条件过滤出来的数据,还在第3页,左侧单选按钮还是选中刚才操作的那个客户。

 

2、跟踪分析

1)客户列表

A、调用MyClientActionexecute()方法,会出现客户列表。该方法中对“详述”按钮的配置代码:

new Button(1, "详述","buttonClick('view.action','all','view')","")

说明向详述页面跳转入,传入requestType的参数值为all

 

B、点击“查询”,客户类别选择“线索客户”,筛选。跳转到第三页,此时右键查看源代码。

form1表单中单选按钮的代码:

<input type="radio" name="RELATION_Client_id" value="402881e43bda139c013bda20deea003f">

 

表单最后有一条代码,它是记录查询条件的,即:客户类别为线索客户。

<input type="hidden" name="SEARCH_clientSortId" value="402880822d032eb6012d038278e70002"/>

 

2)点击“详述”进入详述页。

A、该页面右侧有三个页签,分别为:详述、联系人、历史。

在进入该页之前的action方法中(MyClientActionview方法),我们找到如下三行代码:

new Button(1, "详述", "form2Submit('view.action','all')",""),

new Button(1, "联系人", "form2Submit('listOne.action','all')",""),

new Button(1, "历史", "form2Submit('listFive.action','all')","")

这就是右页签的配置,第二行说明:点击联系人的,跳转到listOne.action,传入的requestType参数为all,form2表单提交跳转的。

 

B、右击查看源代码,发现form2代码如下:

<form action="" name="form2" style="display: none" method="post">
  <input type="hidden" name="requestType" value="all"/>   
  <input type="hidden" name="SEARCH_EgecStart" value="24"/>
  <input type="hidden" name="SEARCH_EgecPerNum" value="12"/>
  <input type="hidden" name="SEARCH_clientSortId" value="402880822d032eb6012d038278e70002"/>
  <input type="hidden" name="RELATION_Client_id" value="402881e43bda139c013bda20deea003f"/>
</form>

记录了分页信息中,开始位置第24条,也就是第三页,每显示12条,查询条件,和当前客户ID

 

3)点击“联系人”右页签,进入联系人列表.

A、在进入之前的actionMyClientActionlistOne方法)中,有如下代码

queryFere.setMastKeep(Constants.RELATION_+className+"_id");

表示将客户ID参数(RELATION_Client_id)加入到mastKeep列表中

 

new Button(1, "修改", "buttonClick('updateOne.action','all','update')","update_1"),

表示点击“修改”按钮时,向修改页面传入的requestType值为all,由form1表单提交完成。

 

B、右击查看源代码,发现form1表单最后几行代码如下:

<input type="hidden" name="SEARCH_EgecStart" value="24"/>
<input type="hidden" name="SEARCH_EgecPerNum" value="12"/>
<input type="hidden" name="SEARCH_clientSortId" value="402880822d032eb6012d038278e70002"/>
<input type="hidden" name="RELATION_Client_id" value="402881e43bda139c013bda20deea003f"/>

仍然带着客户列表的状态数据。

 

4)点击修改,进入联系人修改页面

A、在进入之前的actionMyClientActionupdateOne方法)中,有如下代码

voneFere.setTopButtons(

new Button(1, "确认", "formSubmit('updateOneDone.action','all')",""),

new Button(1, "返回","form2Submit('listOne.action','se')",""));

代表修改页面上的两个按钮:确认和返回。确认时,调用的form1提交的,传入下页面的requestType值为all。返回是调用form2提交的,传入的参数为se

 

B、右击查看源代码,发现form1表单最后几行代码如下:

<input type="hidden" name="SEARCH_EgecStart" value="24"/>
<input type="hidden" name="SEARCH_EgecPerNum" value="12"/>
<input type="hidden" name="SEARCH_clientSortId" value="402880822d032eb6012d038278e70002"/>
<input type="hidden" name="RELATION_LinkMan_id" value="402881e43bda139c013bda20df390069"/>
<input type="hidden" name="RELATION_Client_id" value="402881e43bda139c013bda20deea003f"/>

还带着客户列表的状态,只是多了一个穿越条件,就是联系人的ID值。

 

5)点击“确认”,弹出“修改成功”信息提醒页。

A、在处理提交的actionMyClientActionupdateOneDone方法)中,有如下代码

ActionContext.getContext().put("nextRequextType","se");

它是说明,在下一页面,也就是显示“修改成功”的信息提醒页面中,form表单的requestType元素值采用se,之所以之么做,是因为信息提醒页面展示3秒后,会返回到联系人列表页。联系人列表页面form1中不需要穿越条件,因为它本身有单选按钮,如果也出穿越条件,就会出现两个名称为RELATION_LinkMan_id的元素。而RELATION_Client_id是不会丢失的,因为它放在mastKeep列表中。

 

B、在住息提醒页有如下代码:

<input type="hidden" name="requestType" value="<s:property value="nextRequextType" default="se_no"/>"/>

表示向下个页面(联系人列表)传递的requestType值,是由action中提交过来的,即se

 

6)再次回到联系人列表

A、再次在actionMyClientActionlistOne方法)中查看,有如下代码

new Button(1, "返回","form2Submit('list.action','se_no')","")

表示返回客户列表时,调用的form2表单提交跳转的,传入的requestType参数为se_no

 

B、右击查看源代码,发现form1表单最后几行代码如下:

<input type="hidden" name="SEARCH_EgecStart" value="24"/>
<input type="hidden" name="SEARCH_EgecPerNum" value="12"/>
<input type="hidden" name="SEARCH_clientSortId" value="402880822d032eb6012d038278e70002"/>
<input type="hidden" name="RELATION_Client_id" value="402881e43bda139c013bda20deea003f"/>
</form>

发现上面代码丢弃了RELATION_LinkMan_id在隐藏域,而RELATION_Client_id仍在,是因为前一页面页面传来的requestType值是se,RELATION_Client_idaction中已经加入了mastKeep列有。

 

Form2的表单代码如下:

 <form action="" name="form2" style="display: none" method="post">
<input type="hidden" name="requestType" value="all"/> 
<input type="hidden" name="SEARCH_EgecStart" value="24"/>
<input type="hidden" name="SEARCH_EgecPerNum" value="12"/>
<input type="hidden" name="SEARCH_clientSortId" value="402880822d032eb6012d038278e70002"/>
<input type="hidden" name="RELATION_LinkMan_id" value="402881e43bda139c013bda20df390069"/>
<input type="hidden" name="RELATION_Client_id" value="402881e43bda139c013bda20deea003f"/>
</form>

From2因为是所有的,不受requestType限制,所以全部出来。在此时点击“返回”按钮到客户列表时,客户列表页面出form1表单,这些以RELATION_开头的穿越条件和分页信息都会丢失,因为这我传过去的requestType参数将为se_no注:form2Submit()这个js方法改变requestTyper元素的值)。之所以传这个参数,是因为在客户列表的form1表单中,有单选按钮(名称为RELATION_Client_id)和分页信息,只需要将查询条件作隐藏域即可。

 

7)点击返回到客户列表,可以看到还是以前的查询条件,记录数还是过滤后的条数,单选按钮还停留在之前选中的客户上。

 

四、相关的类

1ShowUtil.java 显示工具类,被jsp调用,输入隐藏域。

2Constants.java 里面定义了几个相关的常量。

3addCommon.jsplistCommon.jsp

4)各个action

 

 

返回《易道客》主页

 

 

 

0
5
分享到:
评论
2 楼 ljf_home 2012-12-28  
sgp420 写道
之前遇见过这样的问题  采取的是第二种方式 一层一层的向下转,总感觉这样会影响速度且不好管理

速度应当不是问题,主要是管理的问题。需要一套严格的机制,并且开发人员需要很熟悉并遵守这套机制,就会得心应手。这个机制是有些复杂,我自己写的,如果有一段时间不写代码,还得回过头来梳理一下它的流程才能完全明白。不过熟悉的话,能应付各种情况,感觉会很方便。有点像学习财务上的借贷记帐法的感觉。呵呵。。。。
1 楼 sgp420 2012-12-28  
之前遇见过这样的问题  采取的是第二种方式 一层一层的向下转,总感觉这样会影响速度且不好管理

相关推荐

    APP跳转神器微信跳转php源码获取weixin://生成跳转代码

    7爱神器简单操作无需复制粘贴,只需要点开链接就可以打开微信,帮助你提升推广效率,目前7爱神器源码一直在更新更多新功能,未来可能会正和应用大部分营销工具,现在已经整合了淘宝京东以及QQ的跳转主要方便开发者...

    STL源码剖析pdf及源码.zip

    《STL源码剖析》是由著名C++专家侯捷编著的一本深入解析STL(Standard Template Library,标准模板库)的权威书籍。这本书详细介绍了STL的核心组件,包括容器、迭代器、算法和函数对象,以及它们在实际编程中的应用...

    PHP网站跳转链接页面源码 一般用在跳转到外部链接.

    在PHP编程中,网站跳转链接页面是一种常见的需求,它用于将用户从当前页面重定向到另一个指定的URL,无论是内部链接还是外部链接。这里我们将深入探讨PHP实现跳转的原理、方法以及如何编写这样的源码。 首先,理解...

    2022最新版本微信QQ防封遮罩跳转页面PHP源码美化版

    微信QQ防封源码_qq遮罩跳转页面PHP源码美化版 浏览器跳转原理就是,用户微信,QQ内访问提示浏览器打开,非微信QQ访问可直接打开。不会有任何提示,对用户没有任何影响,网址跳转到浏览器打开,也就不会再存在封域名...

    HTML输入密码自定义跳转页面源码

    如果正确,使用`window.location.href`属性来改变浏览器的URL,从而实现页面跳转。如果错误,则可能显示错误消息或阻止跳转。 `style.css`文件则用于定义页面的视觉样式。它可以包括元素的颜色、字体、布局等,使...

    android项目源码页面跳转

    本项目源码提供了一个完整的示例,演示了如何在多个页面之间进行有效、流畅的切换。以下是对这个"android项目源码页面跳转"的详细分析。 1. **Intent**: 在Android中,Intent是页面跳转的核心工具。它用于表达一个...

    安全检测GO内外链跳转页面html源码.zip

    3. **JavaScript交互**:为了实现动态跳转和安全检测,源码很可能会包含JavaScript代码,用于监听用户行为,进行必要的验证,并控制页面跳转。 4. **安全验证技术**:可能包含验证码机制,如图片验证码、滑动验证等...

    微信QQ防封源码 qq遮罩跳转页面PHP源码美化版.rar

    微信QQ防封源码_qq遮罩跳转页面PHP源码美化版 做营销最怕的就是自己的域名被举报,变红?特别是微信好qq,今天分享一套微信QQ防封源码_qq遮罩跳转页面PHP源码美化版 搞一个遮罩(跳转浏览器提示)就OK了

    C#中所有页面跳转方式

    `Response.Redirect`是最常见的页面跳转方式之一,它可以跳转到任何URL。这种方式会发送一个新的HTTP请求到指定的URL,并且当前页面会被替换为新页面。 **示例代码**: ```csharp // 跳转到MAIN.aspx页面 Response....

    vue跳转页面的几种方法(推荐)

    vue跳转不同页面的多种方法 1:router-link跳转 &lt;!-- 直接跳转 --&gt; &lt;button&gt;点击跳转2&lt;/button&gt; &lt;!-- 带参数跳转 --&gt; &lt;router to={path:&gt; &lt;button&gt;点击跳转1&lt;/button&gt; ...

    广告跳转安全警告提示源码_广告跳转源码_安全警告提示源码_

    在互联网世界中,广告是许多网站收入的重要来源。然而,广告有时可能会引发用户不期望的跳转,甚至可能隐藏潜在的安全风险,如恶意软件或欺诈链接...对于开发者来说,理解和应用这类源码是提升网站质量的关键步骤之一。

    页面自定跳转 超链接 跳转 jsp页面跳转

    页面自定义跳转指的是在网页设计中,开发者通过编程手段实现的非用户直接操作的页面跳转机制。这种跳转方式可以是基于时间延迟的自动跳转、条件判断后的跳转或者是响应特定事件(如按钮点击)的跳转。而超链接跳转则...

    WPF学习之页面跳转

    **WPF学习之页面跳转** Windows Presentation Foundation (WPF) 是Microsoft开发的一种用户界面框架,用于构建桌面应用程序。在WPF中,页面跳转是实现应用内部导航的关键功能,对于构建多视图、模块化的应用程序至...

    倒计时十秒后跳转到其它页面源代码

    标题中的“倒计时十秒后跳转到其它页面源代码”是指一种常见的网页编程技术,用于在用户停留一定时间后自动重定向到其他页面。这种功能常用于广告页面、临时提示信息或需要用户确认的场景。下面我们将深入探讨这个...

    好看的安全跳转单页html源码.zip

    这个源码可能是为了创建一个简洁、用户友好的页面,用于在用户访问网站时进行安全的重定向。安全跳转在网页开发中很重要,因为它可以防止用户误入恶意网站,同时保证数据传输的安全性。 描述中的“好看”意味着源码...

    qt-quick QML页面跳转

    下面我们将深入探讨如何在Qt Quick中实现QML页面跳转,包括单页面跳转和多页面跳转。 首先,我们需要理解QML的基本结构。一个QML文件通常代表一个可视化的组件或页面。通过定义`Item`或其子类(如`Rectangle`、`...

    网站简约404页面倒计时跳转源码.zip

    在网页设计中,404页面是用户访问...总的来说,这个压缩包提供的源码可以帮助你创建一个既实用又具有用户体验考虑的404错误页面,通过倒计时跳转功能,有效地引导用户离开错误页面,减少网站的跳出率,提高用户满意度。

    mvc页面跳转实例

    本实例主要关注的是“页面跳转”和“权限判断”两个关键知识点。 1. **页面跳转**: 页面跳转在Web应用中是相当常见的操作,它允许用户在不同的页面之间导航。在ASP.NET MVC框架中,有多种实现页面跳转的方式。一...

    js实现页面跳转的几种方式

    在Web开发中,页面跳转是十分常见的操作之一。通过JavaScript,我们可以非常灵活地控制页面的导航逻辑,提高用户体验并优化应用性能。本文将详细介绍几种常用的JavaScript页面跳转方法,并分析各自的适用场景。 ###...

    QT 实现登陆页面跳转到主页面源码

    本教程将详细解释如何使用QT来实现从登录页面到主页面的跳转。 首先,我们需要理解QT中的基本组件。在登录页面,通常会包含用户名输入框(`QLineEdit`)、密码输入框(通常为`QLineEdit`,但设置为密码模式以隐藏...

Global site tag (gtag.js) - Google Analytics