Tapestry最新版5.1.0.5教程(三)

    在讲述页面之间传递值之前首先要介绍一个Tapestry的页面缓存。
    Tapestry的一个经常被提及的就是页面的缓存,Wicket也有页面缓存,但是Wicket的页面是缓存在Session里的,缺省好像是只缓存5个页面。这一点让我对Wicket的印象打了折扣,首先,这种机制在高并发,也就是多人同时在线的时候,感觉页面缓存会占用大量资源。而Tapestry的页面缓存是在一个大池中。
    页面缓存的优点就是提高效率,但是缺点也是比较明显的,那就是给开发实现带来了不方便。我觉得众人说的Tapestry的学习曲线比较陡,一部分原因就在这里。上一章讲过,在Tapestry中,页面的跳转是通过InjectPage实现的。Tapestry在页面跳转时,会从缓存池中选取一个相应页面的实例,渲染成html。关键在于Tapestry在把页面放到缓存池之前,会把页面实例里的值清空。这就是造成页面传值麻烦的原因。写段代码示例:
class Register {
    private String name;
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}

class Start{
    @InjectPage
    private Register register;

    Object onSubmit() {
        register.setName("superman");
        return register;
    }
}

    如果页面从Start跳转到Register,并且希望把superman这个值传递给Register这个页面,感觉上只要象上面这段代码一样简单设置一下就行了,但是实际上这样是无法在Register的页面上显示出superman这个名字的。因为Tapestry会在页面显示时候的时候,从缓存池中提取一个实例,这个实例在放入缓存池之前,name属性的值就被清空了。

下面是Tapestry页面之间传递值的几种方式:
1、Persist。最简单的方式是使用persist注解。
class Register {
    @Persist
    private String name;
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}

   只要这样指定后,Tapestry会把name的值保存在Session中,以备下次使用。但是这样的缺点也很明显,首先是占用资源,另外这样的URL是不能作为书签的,因为参数值不体现在URL中,而是保存在Session中。

2、Page Active Context。这个方法比较好,但是需要一些代码来实现。主要是添加两个函数onActivate和onPassivate。
Class Register {
    private String name;
    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    void onActivate(String name) {
        this.name = name;
    }
    String onPassivate() {
        return name;
    }
}

    在Start页面中,我们使用了InjectPage把Register注入到了类中,如果只是简单地返回Register,是不能正确显示name的值的,但是在Tapestry会在把Start页面中的Register放回缓存池,清空Register实例中的变量值之前,检查这个类是否存在,但是现在我们实现了onActivate和onPassivate这两个方法,Tapestry会自动将onPassivate返回值保存起来,然后从页面池中取得页面后,再把刚才保存的值作为参数传递给onActivate方法。

3、SessionState
    在Tapestry中有一种类型的对象存储在Session中,所以对所有页面都是可见的,但是又不需要对页面暴露Session。在Tapestry5以前,称之为ApplicationStateObject,但是这个称呼并不准确,因为这个对象不是Application级别,而只是Session级别,所以Tapestry5开始,改名为SessionStateObject。
    使用方法也很简单,只需要在JavaClass中,给相应的属性添加一个@SessionState注解即可。
    需要提醒注意的是,SessionState区分对象实例不依赖于实例的名称,而是根据实例的类型,比如:你在一个类中使用@SessionState注解了一个String name;而在另一个类中想再用@SessionState注解一个String password;这是不行的,Tapestry会把这两个当作同一个对象实例。
    另一个需要注意的是,SessionState注解之后,Tapestry会马上会初始化生成一个该对象的实例。

原文地址:[url]http://www.blogjava.net/usherlight/archive/2009/06/05/280207.html [/url]

你可能感兴趣的:(.net,tapestry,wicket)