本文翻译出处 http://tapestry.apache.org/tapestry5/tapestry-core/guide/event.html
本人翻译目的是用来学习Tapestry5的,共享出来希望大家批评指正。计划持续翻译。
chinajavawolf
Component Events
组建事件
组件事件是组件意识到用户行为的方法,就像点击链接和提交表单。
组件事件被用来两种用途:
- 他们表现为用户在客户端浏览器中触发链接或提交表单时发起的请求。这些在页面导航page navigation和请求处理requst processing中被更全面的描述。
- 他们表现为请求中的控制流,允许一个组件去通知他的容器关于一些详情(“一个表单被提交”), 或者从容器中收集一些片断数据。
经常,一个导航请求(由用户发起)将产生许多控制流请求。例如:一个表单组件将被一个动作请求触发,并且随后将在表单提交被要处理时发出一个通知事件,无论成功与否。
在Tapestry4里,你可以使用方法名配置一个组件参数,当某一事件发生时该方法被调用,通常是一个客户端请求。
这有一些局限性,包括事实上仅有一个方法被调用。
Tapestry5引入了事件处理器方法概念,他通过命名约定或者OnEvent标注来确定。事件处理器方法可以拥有任何可见度,甚至是私有的(通常他们被提供包级别的可见度,以支持测试)。
你指定一个或多个方法去监听组件事件要优于配置一个组件去调用特定的方法。单独的一个事件处理器方法可以接收多个不同组件的通知事件
例如,这是页面的一部分(让我们称他为“Chooser”),用来让用户选择从1到10的数字。
- <p> Choose a number from 1 to 10: p>
-
- <p>
- <t:count end="10" value="index">
- <a t:id="select" t:type="actionlink" context="index">${index}t:comp>
- t:count>
- p>
ActionLink组件产生一个动作
URL.
URL标识了页面包含的组件("chooser"),事件类型(除非他是“action”,默认的和最常用的事件类型),页面中的组件id(“select”),加上附加的上下文值(s)。
例: URL: http://localhost:8080/chooser.select/3.
当有附加的上下文值时,他们被追加到路径里。
这里示范一个Tapestry和传统框架动作的关键区别。这里的URL并不是说链接被点击时发生了什么,而是标识哪个组件来响应。
从URL到一小段代码没有简单的映射;这里通过调用事件处理器方法的形式来替代组件发送通知。
当组件链接被用户点击的时候,一个Java方法被调用。
- @OnEvent(component = "select")
- void valueChosen(int value)
- {
- _value = value;
- }
Tapestry 在这要做两件事情:
- 确认valueChosen()方法作为被调用的方法。
- 将上下文值从字符串转换为整形并交给方法处理。
在上面的例子中,valueChosen()方法将被choose组件产生任何事件时调用(至少有一个上下文值)。
因为ActionLink组件仅产生单个事件类型,即"action",这不会有任何问题。
有些组件能产生多种事件类型,些时你将需要更多的细节参数:
- @OnEvent(value = "action", component = "select")
- void valueChosen(int value)
- {
- _value = value;
- }
OnEvent标注的属性值和事件名相匹配。
"action"是默认的事件类型名;ActionLink和表单组件都适用这个事件类型。如果你省略了OnEvent标注的组件部分,那么你将收到所有包含的组件通知事件,可能包括嵌套的组件(由于事件的冒泡机制)。
你可以明确限定希望接收哪个组件的事件。
事件处理器方法命名约定
作为使用标注的一种替代,你可以以指定的方式命名事件,Tapestry将会调用你的方法就像他们被标注了一样。
这种方式的命名方式是在事件控制器方法前面使用"on"前缀,跟着是动作名(首字母大写)。接下来你应该追加"From"和一个首字母大写的组件id.
前面的例子可以被重写成:
- void onActionFromSelect(int value)
- {
- _value = value;
- }
如果事件类型命名为"onAny",它将接受所有事件类型,你很少需要此种方式!
Howard的提示:我发现我更喜欢命名约定,保留标注只是为了其他不适合的情形。
事件上下文
上下文值(ActionLink组件的context参数)可以是任何对象,然而,仅发生一个简单的字符串转换。与Tapestry 4相比,他有一个精细的类型机制有一个古怪的名字叫"DataSqueezer"。
此外,不管你的值是什么(string, number, date),它都会被转换为无格式字符串。这将形成一个更容易读的URL。
如果你有多个上下文值(通过将一个对象list或数组绑定到ActionLink的上下文参数),则每一个值都将按序地被追加到URL中。
当一个事件处理器方法被调用,将发生一个强制从字符串到实际类型的转换。事件处理器方法仅当上下文值的数量至少与方法参数数量一致时被调用,带有过多参数的方法将被忽略。
另外,一个事件处理方法还可以带上一个java.lang.Object[]类型的参数。这个参数会接收整个上下文数组。这是有用的,例如,这在上下文不同时间为不同长度时。我们可以使用一个个显式的参数或者单个的Object[]类型的参数。
事件冒泡机制
事件会冒泡向上传递到层级,直到它被终止。当事件处理方法返回一个非null值时事件被终止。
对于页面导航事件,事件处理器方法的返回值决定了Tapestry将如何呈现响应。