Tapestry学习十二:关于组件(七)IF和checkbox组件

本文介绍如何使用Tapestry框架设计用户注册表单,包括复选框控制订阅功能、表单状态持久化及取消订阅选项的设计。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 
在用户注册的时候,我们想要给他们选择是否预定我们的时事资讯,那么我们就要新增一个选择框:
 
界面变的稍微复杂了,但是也给了我们一个学习新组件的机会。当用户点击该复选框,复选框应该消失,接受用户的电子邮件的文本框应该会出现。
 
在页面中的代码:
<tr> 

<t:if t:test="subscribe"> 

<td><t:label t:for="email"/></td> 

<td> 

<input type="text" t:type="textfield" t:id="email" t:value="email"/> 

</td> 

<t:parameter t:name="else"> 

<td colspan="2"> 

<input type="checkbox" t:type="checkbox" t:value="subscribe" 

onclick="this.form.submit()"/> 

Check the box to subscribe to our Newsletter. 

</td> 

</t:parameter> 

</t:if>

</tr>

 
让我们看看它们是怎么在一起工作的,首先,这只是一行,放在Registration.tml的单选按钮之下,这一行包含了一个t:if标签。
<t:if t:test="subscribe">
...
</t:if>
组件唯一的参数就是test,他提供了一个boolean值,它默认的前缀是prop所以Tapestry会到page class中调用getSubscribe方法。如果这个方法返回true,那么在If组件下的内容将显示:
<td><t:label t:for="email"/></td>
<td>
<input type="text" t:type="textfield" t:id="email"  t:value="email"/>
</td>
 
这个IF组件还有一个被命名为elsePatameter项,这个Patameter提供这个在getSubscribefalse时,将会展现的内容。
<t:parameter t:name="else"> ... </t:parameter>块中萎缩这一个在HTML控件中的组件,这个组件就是checkbox,注意看他的value有一个值叫subscribe,是和IF组件的test属性一样的。
而且这个Checkbox组件居然和一个js勾搭在了一起,当checkbox被点击的时候,就会惹到这个javascript,不过这个JS只是提交了这个表单。
让我们看看他们是怎么互相勾搭在一起的,刚开始的时候,Registration页面第一次被加载,subscribe被认为是false,那么这个checkbox就被显示了出来。如果这个用户去点击了这个checkbox,那么这个form就被提交了,然后subscribe就被置为true,我们想要page去记住这个值,那就只要让这个值persistent.了。那么那个输入email的文本框就出现了。
 
我们需要在page class中加入能让subscribe持久化的属性,和保存email的属性:
@Persist

private boolean subscribe;

private String email;

public boolean isSubscribe() 

{ 

return subscribe;

}

public void setSubscribe(boolean subscribe) 

{ 

System.out.println("Setting subscribe: " + subscribe); 

this.subscribe = subscribe;

}

public String getEmail() 

{ 

return email;

}

public void setEmail(String email) 

{ 

this.email = email;

}

 
setter方法中有个output方法,这将方便的告诉我们这个page class是怎么工作的。
运行这个工程,输入用户名密码,并且选择接受订阅,一切都在掌控之中,email的输入框取代了checkbox。但是你也会发现别的问题,我们输入的用户名和密码都不见了,或者恢复到了默认值。如果你对前面的还有印象,你不会感到有任何的疑问,毕竟除了我们让它这么做不然Tapestry是不会保存任何东西的。这也很简单,只要在想要记住的属性前加上@persist就可以了:
@Persist

private String userName;

@Persist

private String password;

private String password2;

@Persist

private String email;

@Persist

private Gender gender = Gender.FEMALE;

 
实际上密码是不用持久化的,因为它永远都不会显示,但让他持久化一会儿就有点小用。现在页面能好好的工作了,但是有一个问题,当我们选择了接受,我们就没法再取消,因为subscribe被赋值为true并保持在session中,我们没有提供一个方法去再让它变回false。除非你把浏览器关了重新来,但是白痴才会这么做。
 
为了解决这个问题,我们在email下面加上另外一个checkbox
<td> 

<input type="text" t:type="textfield" t:id="email" t:value="email"/> 

<input type="checkbox" t:type="checkbox" 

t:value="unsubscribe" onclick="this.form.submit()"/> 

I don't want to subscribe

</td>


 
当然还要在Registration.java中加入unsubscribe属性:
 
private boolean unsubscribe;
public boolean isUnsubscribe()
{
return unsubscribe;
}
public void setUnsubscribe(boolean unsubscribe)
{
this.unsubscribe = unsubscribe;
}
 
当我们点击这个checkbox时,form被提交,unsubscribe被置为true。但是我们怎么样才能使unsubscribetrue的时候subscribe被置为false呢?很自然的,我们需要在form提交的时候做这个事情:
 
void onSubmitFromRegistrationForm()
{
System.out.println("The form was submitted!");
if (unsubscribe) subscribe = false;
}
 
现在唯一的问题就是密码在页面重载时不能重新显示,虽然我们已经让密码的属性持久化了。其实这是很自然的,passwordFeild组件不能重新显示它的值。但是我们不能让我们的用户在每次页面重新加载时,都重新输入密码,这是不道德的。
 
下面作者想出了一个天才的解决方案:就是在提交后把密码输入框隐藏。
<t:if t:test="passwordNotSubmitted"> 

<tr> 

<td><t:label t:for="password"> 

Label for password</t:label>:</td> 

<td><input type="text" t:type="passwordfield" 

t:id="password" 

t:value="password"/></td> 

</tr> 

<tr> 

<td><t:label t:for="password2"> 

Label for password 2</t:label>:</td> 

<td><input type="text" t:type="passwordfield" 

t:id="password2" 

t:label="Repeat password" t:value="password2"/></td> 

</tr>

</t:if>

 
并且在class中加:
public boolean isPasswordNotSubmitted()
{
return userName == null;
}
 
现在我们已经有了一个相当灵活的页面,只需要写少量的代码就能实现我们的目的。其中所有的方法都是在提交表单的处理事件中实现的。但是,这些都只是玩具代码,只是演示页面是如何变化的。我们的目的是注册一个用户,但是用于提交form的事件已经用于了不同的实现,那么我们该把代码写到哪里?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值