Sunday, October 26, 2008

Explain onActivate/onPassivate of Tapestry5

用Tapestry5开发页面过程中,最常用到的二个页面方法(事件处理器)就是onActivate()和onPassivate()。
onActivate()方法是在此页面被激活后调用的,可以用此方法接收传给页面的参数(用官方的说法是以Array/List形式返回页面的activation context),此方法可以通过重载来接收数量不同的参数,并且其中参数少于等于URL InternalConstants.PAGE_CONTEXT_NAME传进来的参数数量的onActivate()方法都会被调用一次,其中无参的onActivate()方法肯定会被调用,并且是最后被调用,如后面例子所示。

注意,如果在Tapestry5中集成了tapestry-hibernate包,并且在passivate context中返回的是Hibernate实体的情况下,则可以在onActivate()中直接接收这些Hibernate实体对象,Tapestry会在passivate时自动从这些实体对象中提取id到页面URL ,并且在activate时自动转回Hibernate实体对象。Tapestry会在后台去查询数据库,如果页面很简单可以这么用,复杂页面不建议这么做。

onPassivate()方法是在页面渲染中,由LinkFactory生成每个actionLink或者返回自身页的pageLink时都会触发此事件,因此这个passivate事件在一个页面渲染中可能会重复调用多次。会将此方法返回的结果被encode后赋给InternalConstants.PAGE_CONTEXT_NAME,固化到所有返回自身页面的URL后面。对于actionLink和pageLink稍有不同的是,actionLink不管事件处理后重定向去哪,URL后都会跟上此参数,因其事件触发后先返回自身页面,而pageLink如果是指向别的页面,则不会触发此事件,URL后也不会带上此参数,如果需要传参给其他页面则通过pageLink的context参数指明参数值,如果pageLink是返回自身页面,则跟actionLink一样会在URL上直接跟上onPassivate返回的值,这样当前页面的一些变量状态就可以不用@Persist,而用onPassivate/onActivate进行传递。

关于onActivate/onPassivate更详细的内容可从以下接口和类中了解:ComponentResources/ComponentEventRequestHandler/ComponentEventRequestFilter/ComponentEventRequestHandler/ComponentEventRequestParameters/ComponentEventDispatcher/EventConstants/InternalConstants/LinkFactory/LinkFactoryImpl/PageLink/EventLink/ActionLink等。

其中ComponentEventRequestHandler可处理的事件请求形式有:

* /context/pagename:eventname -- event on the page, no action context
* /context/pagename:eventname/foo/bar -- event on the page with action context "foo", "bar"
* /context/pagename.foo.bar -- event on component foo.bar within the page, default event, no action context
* /context/pagename.foo.bar/baz.gnu -- event on component foo.bar within the page, default event, with action context "baz", "gnu"
* /context/pagename.bar.baz:eventname/foo/gnu -- event on component bar.baz within the page with action context "foo" , "gnu"


关于onActivate/onPassivate的一个测试例子:
java:
public class Test {

void onActivate() {
System.out.println("must be revoked when page be requested");
}

void onActivate(int id) {
System.out.println(id);
}

void onActivate(int id1, int id2) {
System.out.println(id1);
System.out.println(id2);
}

int onPassivate() {
System.out.println("passivate context");
return 1;
}

void onActionFromLink() {
}

void onRedirect() {
}
}
tml:
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
<a href="/Test">Test</a>
<br />
<t:actionLink t:id="link">ActionLink</t:actionLink>
<br />
<t:eventLink t:event="redirect" t:context="literal:1">EventLink1</t:eventLink>
<br />
<t:eventLink t:event="redirect">EventLink2</t:eventLink>
<br />
<t:pageLink t:page="Test">Self page Link</t:pageLink>
<br />
<t:pageLink t:page="Start">Another page Link</t:pageLink>
</html>
其中onPassivate()方法会被调用4次。
Reference:
http://tapestry.apache.org/tapestry5/apidocs/org/apache/tapestry5/internal/services/ComponentEventDispatcher.html

No comments :