§2-3
在学习笔记2中,最后我们实现了这样的功能:在监听方法中,获取将要跳转的页面,然后设置那个页面的某个属性值,最后返回页面对象,实现跳转、传值功能。 下面我们在page组件配置文件中来实现获取跳转页面类的功能。
使用的是page组件配置文件的<inject>标签.
Home.page
<
page-specification
class
="com.simpleForm.pages.Home"
>
<
inject
type
="page"
object
="Result"
property
="resultPage"
/>
<
component
type
="Form"
id
="myForm"
>
<
binding
name
="listener"
value
="listener:onSubmit"
/>
</
component
>
<
component
type
="TextField"
id
="username"
>
<
binding
name
="value"
value
="ognl:username"
/>
</
component
>
</
page-specification
>
修改Home.java
package
com.simpleForm.pages;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
import
org.apache.tapestry.IPage;
import
org.apache.tapestry.IRequestCycle;
import
org.apache.tapestry.html.BasePage;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
public
abstract
class
Home
extends
BasePage
...
{
abstract public Result getResultPage();
private String username;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public String getUsername() ...{
return username;
}
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
public void setUsername(String username) ...{
this.username = username;
}
public IPage onSubmit(IRequestCycle cycle)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
System.out.println("提交的值是:"+username);
Result resultPage=getResultPage();
resultPage.setResultValue(username);
return resultPage;
}
}
将Home类改写成abstract抽象类,并添加getResultPage();抽象方法.在onSubmit方法里就是通过它来得到一个Result类实例的.
<inject>是不是就是往Home类里注入一个Result类的属性? type=page object=Result property=resultPage
§2-4
DWDED 教程里就前面已经做的例子提了这样一个bug
当提交并显示结果后,不将页面关闭. 再打开一个结果页面,页面上显示的将是前一次提交的结果.而这个并不是我们所希望的,
应该初始化为空.
解决的方法是在Result.java里添加一个初始化的方法:
protected
void
initialize()
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
resultValue="";
}
这样每次请求的话,都将把resultValue初始化一下. 构造函数里初始化一下不行吗?不行,我试过了.
具体它是怎么一个执行过程我还不是很了解.好像是使用了Page Pool技术,每次请求该页面的时候是去pool里取,这样看来也就不会去执行构造函数了.
上面那个resultValue其实应该让它等于null.
其实呢,这个initialize的功能完全可以交给tapestry去做,把这个属性写到怕个组件配置文件里.
Result.page
<
page-specification
class
="com.simpleForm.pages.Result"
>
<
property
name
="resultValue"
/>
<
component
id
="resultValue"
type
="Insert"
>
<
binding
name
="value"
value
="ognl:resultValue"
/>
</
component
>
</
page-specification
>
<property>标签会使应用程序在运行时生成一个Result的子类,该子类中有initialize,get,set方法.同时呢,你还需要将那个Result类写成abstract类.
Result.java
package
com.simpleForm.pages;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
import
org.apache.tapestry.html.BasePage;
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
public
abstract
class
Result
extends
BasePage
...
{
abstract public void setResultValue(String resultValue);
}
<property>注入了一个属性到页面里..<property>标签还有一个属性叫 init-value ,这个可以初始化一个你需要的值给注入变量.如果没有的话,注入的变量的初始值将是默认值,比如String 是null,int是0,boolean是false等.
上面的代码中之所以只有set方法而没有get方法,是因为在Home.java的onSubmit方法中,我们在获取了Result类后需要set方法,Result类无法调用隐式生成的子类的set方法,所以显示地声明一下是必须的.
Home.java中有一个username属性,也可以使用注入方式注入页面.
§2-5
下面有个高级的东西来实现pages和properties的注入——annotations,这个我很少用,不过我知道用它可以很方便的实现很多功能。省得你去写配置文件了。
把Home.page中的<inject object="Result" type="page"'>删掉...
在Home.java中原来不是应该有个getResultPage()的抽象方法吗?在那上面@加上下面的这行代码:
@InjectPage("Result")
不过这个要求jdk1.5至少, 1.4不支持这样的语法...
在NetBeans中查看项目的属性,更改源代码级别为1.5或者更高,就可以了..
有@InjectPage却没有@InjectProperty ....这是因为,在tapestry中.当发现一个未被实现的抽象getter(或者它继承自接口),tapestry会自动为其加上一个property..所以呢,这里把<property>标签删了就可以了...
那初始化怎么办?......在abstract public String getUsername();上面使用如下的annotations:
@InitialValue("username") 啊就可以了..