Tapestry 5 页面导航

Tapestry 5 页面导航
 
 
本文根据 http://tapestry.apache.org/tapestry5/tapestry-core/guide/pagenav.html 翻译整理过来,请高手指正,转载请注明出处!
 
 
本质上, Tapestry 应用是许多相关的工作在一起的页面的集合。从某种程度来说,每一个页面就是一个应用。
 
任何单个的请求对应一个页面。请求来源于两种形式:
  • 动作请求(Action Requests)指向一个特定的页面组件,在组件内部触发一个事件。
  • 呈现请求(render requests)指向一个特定的页面,将页面的HTML标记流输出到客户端。
动作请求与呈现请求的划分是 Tapestry 5 中新出现的概念,它的某些方面是基于 Portlet 规范的思想,区分出这两种类型的请求减轻了许多在传统 web 应用中当用户使用浏览器的后退按钮或点击刷新按钮时的问题。
 
动作请求
 
动作请求表现为超链接( ActionLink )或表单提交( Form )的形式。
这两种情况,事件处理方法返回的值控制着送往用户端 web 浏览器的响应。
 
动作请求的 URL 包含页面名字、组件的嵌套 id 和在组件中触发事件的名字(通常是 "action" )。此外,一个动作请求可以包含额外的上下文信息( context information ),以提供给事件处理方法(与方法参数有关)。
 
这些 URL 暴露了一些应用的内部结构。随着时间的推移,一个应用在维护中组件的 id 可能会改变,这就是说动作请求的 URL 不能被收藏(存为书签)。幸运的是,用户很少有这种机会来改变组件的 id (参见下文):
 
以下是动件请求事件处理方法(动作的监听方法)的不同返回说明。
 
Null response
 
如果一个事件处理方法没有返回值或者返回 null ,此时当前页面(包含该组件的页面)会呈现响应(即响应请求)。
当前页面的页面呈现链接被创建并重定向到客户端。客户端浏览器随后提交的将是一个产生新页面的新请求。用户将会在浏览器看到一个新产生的内容。地址栏里的 URL 将会是一个呈现请求的 URL ( render request URL )。呈现请求的 URL 简短且包含较少的应用结构信息(比如,他不包含组件 id 和事件类型)。呈现请求 URL 是可供用户收藏的。动作请求 URL 是暂时性的,仅当应用处于激活状态时有意义,这并不意味着可以用于随后的 session 。
 
String response
 
当返回一个字符串时,此字符串应该是页面的逻辑名(而非页面的全类名)。另外,页面的名字不区分大小写。
其次,呈现请求的 URL 被构造并重定向到客户端。
 
Page response
 
我们也可以返回一个页面实例,而非一个页面名字。
一个页面可以通过 InjectPage annotation 被注入。
通常,我们会在页面返回前以某种方式设置页面(举例如下,即对页面属性对象赋值)。
你也可以返回页面内的一个组件,但些时将会产生一个运行时警告。
 
Link response
 
事件处理方法可以直接返回一个 Link 实例, Link 被转换为 URL 然后重定向 URL 到客户端。
ComponentResources 对象可以被注入到页面或组件中,它的方法可以创建 action 和 page 链接(它们实际上定义在 ComponentResourcesCommon 中)。
 
Stream response
 
事件处理方法也能返回一个 StreamResponse 对象,这个对象封装了一个送往客户端浏览器的流( stream )。这对把组件产生的 image 或 PDF 送往客户端是很有用的。
 
Object response
 
事件处理方法返回任何其他对象类型都是错误的。
 
页面呈现请求( Page Render Requests
 
呈现请求在结构与行为上要比动作请求简单。简单情况下, URL 仅仅是页面的逻辑名。
 
页面可以有一个活化上下文( activation context )。活化上下文表现为页面状态的持久化信息。实际上,活化上下文通常是一些数据库持久化对象的 id 。
 
当一个页面有活化上下文时,上下文的值被追加到 URL 路径中。并不是所有的页面都有活化上下文。
 
当呈现请求链接被创建时,活化上下文可以被显式设值( PageLink 组件有一个 context 参数可以用来设值)。当没有提供显式活化上下文时,页面会自己查找它的活化上下文。
 
这种查找表现为事件的触发。事件名字为 passivate (我们马上会看到它的一个相对应的名字 activate )。方法返回的值被用做上下文。
 
For example:
 
 
 
 
 
 
 
 
 
活化上下文可以由一连串的值组成,即方法返回的是数组或 List 列表。
 
页面激活Page activation
 
当一个页面呈现请求到来时,页面会在它呈现前被激活。
激活主要为了两个目的:
  • 它允许页面把内部状态数据编码到URL中(上面讨论到的活化上下文)。
  • It provides coarse approach to validating access to the page.它提拱了粗略的方法来校验页面是否可被访问。
后者提到的校验,通常涉及到用户标识及访问;如果我们的页面仅允许特定的用户访问,就可以用页面的激活事件来负责这个访问的校验。
一个页面的激活事件处理器( activate event handler )对应着它的钝化事件处理器( passivate handler ):
 
 
 
 
 
 
 
 
在此相关的部分是:当页面呈现时,它可能包含更多的动作请求 URL (链接与表单)。那些链接与表单的动作请求也一样通过激活页面开始,然后再执行其他的操作。这形成了一个不断的包含同样活化上下文请求链。
 
从某种程度上说,我们也可以使用持久化页面值( persistent page value )来完成相同的效果,但这种方法需要一个激活的 session 且 URL 不可收藏。
 
激活事件处理器(方法)也可以返回一个值,它与动作请求的事件触发器返回的值是一样的。这通常用于访问校验场景。
页面导航模式(Page Navigation Patterns)
动件链接和上下文及页面上下文可以以许多方式组合在一起。
让我们通过一个产品分类页来介绍一个经典的主列表 / 详细页关系的例子。在这个例子中, ProductListing 页面是产品的列表页, ProductDetails 页是相应的显示特定产品的详细页。
 
动作请求/ 持久化数据
 
这种模式下, ProductListing 页面使用动作事件, ProductDetails 页面使用了持久化属性。
 
ProductListing.html:
 
ProductListing.java:
 
 
 
 
 
 
 
 
 
ProductDetails.java:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
以上代码极少,也许对原型来说已经足够好了。
当用户点击一个链接时,动作请求 URL 起初类似 http://.../productlisting.select/99 ,然后最终的呈现请求的 URL 将会类似 http://.../productdetails 。注意产品 id ( "99" )并没有显示在呈现请求的 URL 中。
 
它还有一些次要的缺点:
  • 它需要一个session(用来在请求之间保存_productId属性)。
  • 如果ProductDetails页面在被访问前已设置了一个有效的产品id,就有可能失败(原有值丢失)。
  • URL并没有指出产品的标识,如果用户收藏了这个URL,随后他们会引发先前的情况(没有有效的产品id)。
动作请求/ 活化上下文(Action Requests / Persistent Data ??)
 
我们可以使用 passivation 和 activation 上下文来避免使用 session ,使得链接更可收藏,从而在不改变 ProductListing 页面的情况下改进先前的实例。
 
ProductDetails.java:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
这里的改变保证了呈现请求的 URL 包含产品 id ,如 http://.../productdetails/99
 
此种方法的优点是页面到页面的连接发生在类型安全的 Java 代码中—— ProductListing 页面的 onActionFromSelect 方法。它也有不好的地方就是点击一个链接服务端需要两次往返过程(由两个页面完成这一请求)。
 
呈现请求一次
 
这是一件最通用的主列表 / 详细页的版本。
 
ProductListing.html:
 
ProductListing.java:
不需要代码来处理链接。
 
ProductDetails.java:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
不再需要setProductId() 方法。
 
局限性
 
随着我们应用流程的扩展,我们可能会发现找不到一个合理的方式去避免在不同的请求间(在页面活化上下文之外)持久化某些数据。比如:如果从 ProductDetails 页面开始,允许用户导航到相关的一些页面然后又返回到 ProductDetails 页面,这就开始需要在页面到页面再到页面间保持传递的产品 id 。
 
在某些方面,持久化值更有意义。随后,我们将会实现客户端持久化策略( client-side persistence strategy ),它将对持久化数据进行编码,如产品 id 属性将自动的加入到查询参数中(和隐藏的表单域)。
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值