技术开发 频道

Tapestry 5 组件类

    页面与组件

    在Tapestry 5中,页面与组件的区别已经非常小了。实际上仅有的不同就是包名:${root}.pages.PageName用于页面,${root}. components.ComponentType用于组件。

    Tapestry 4中,页面与组件的区别很大,暴露出分隔的接口以及用于编码继承的抽象实现体系。

    Tapestry 5中,页面仍用于表现,但它已真正成为Tapestry的内部(internal)类。页面组件仅仅是页面组件树的根组件。

    类转换

    Tapestry 以使用你的类做为出发点,在运行时对类进行转换,其原因就包括Tapestry如何在多个请求中缓存(pools)页面。
For the most part, these transformations are both sensible and invisible. In a few limited cases, they are maginally leaky -- for instance, the requirement that instance variables be private -- but we feel that the programming model in general will support very high levels of developer productivity.

    类转换多半是合理的且不可见的,少数受限的情况下,它们的被忽略无关紧要——比如,一个实例需要是私有的——但是我们会发现设计模式通常会支持一个更高的开发效率。

    因为转换发生在运行时,所以转换时并不会影响你实际中创建的Tapestry应用。此外,测试时你的类完全是简单的POJOs。

    类重载

    Component classes are monitored for changes by the framework. Classes are reloaded when changed. This allows you to build your application with a speed approaching that of a scripting environment, without sacrificing any of the power of the Java platform.

    框架监视着组件类的改动,类改变时会被重载。Classes are reloaded when changed.这允许你在不需要牺牲任何Java平台能力的情况下,构建应用的速度接近于脚本环境。

    实例变量

    Tapestry组件可以包含实例变量(不同于Tapestry 4,你得使用抽象属性)。

    实例变量必须是私有的。Tapestry将会执行运行时类的修改来支持实例变量,而且仅对私有变量有效。类中可以有非私有的变量,由于Tapestry池化和重新使用页面与组件,你这时会看到应用中的意外行为。对含有非静态且非私有的属性变量,Tapestry将输出一个错误日志。

    注意你需要提供getter和settter方法访问你类的实例变量。Tapestry不会自动做这事。

    瞬态实例变量

    除非你的实例变量被annotation装饰,否则它就是瞬态的实例变量。这意味着它们的值在每一个请求结束时(当页面从请求中分离时)被重置为默认的值。

    假如你的变量能够在多个请求中保持它的值,你就需要在变量上使用Retain annotation来打破这一重置的规则。你需要注意的是没有客户相关的数据存入在这个属性变量里,因为后面的请求,相同页面实例可能被不同用户所使用。与此同时,相同用户后来的发出请求,也可能是不同的页面实例被使用。

    使用持久化属性变量(persistent fields)在多个请求中保持信息。

    此外,final属性变量不会被重置。

    构造器    Tapestry将会使用默认的无参构造器来实例化你的类。其它构造器将被忽略。
    注入     依赖注入(Injection)通过附加的annotations发生在属性级别。在运行时阶段,属性包含的注入将变为只读性的。
    参数     组件参数(Component parameters)也使用私有的类属性来表示,要在属性上加上Parameter annotation。
    持久化属性   属性可以被加上annotation以便它们在跨请求中保持值。
    内嵌的组件 组件通常包含其他组件,组件内置在其他组件里时就叫做内嵌的组件。包含内嵌组件的组件,其模板将包含元素来识别内嵌组件放置在何处。

    我们可以在模板中定义组件的类型,或者使用Component annotation定义组件类型与参数来创建组件实例变量,对于后者你不能提供元素的类型属性,在模板中只提供id属性就行(假如你提供类型属性的话,Tapestry将会使用使用被annotation声明的属性的类型并输出一个错误日志)。 

package org.example.app.pages; import org.apache.tapestry.annotations.Component; import org.example.app.components.Count; public class Countdown { @Component(parameters = { "start=5", "end=1", "value=countValue" }) private Count _count; private int _countValue; public int getCountValue() { return _countValue; } public void setCountValue(int countValue) { _countValue = countValue; } }

    以上定义的内嵌组件id为"count"(此id源自属性的名字)。组件的类型是org.example.app.components.Count。Count组件的参数start和end绑定了字面值(literal values),value参数绑定了Countdown组件的countValue属性。

    需要注意的是组件类里默认的绑定前缀是"prop:",以上实例中我们可以写成"value=prop:countValue"来完整的显示绑定。

    然而,某些字面值,比如上例中的数字字面值被接受为prop:前缀,即使他们并不是真正的属性(这给应用开发者带来了极大的方便)。我们也可以使用"literal:"前缀,"start=literal:5"可以完成同样的事情。

0
相关文章