天天看点

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

  在用户注册的时候,我们想要给他们选择是否预定我们的时事资讯,那么我们就要新增一个选择框:

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

  界面变的稍微复杂了,但是也给了我们一个学习新组件的机会。 当用户点击该复选框,复选框应该消失,接受用户的电子邮件的文本框应该会出现。

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

  在页面中的代码:

<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" 

οnclick="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 组件还有一个被命名为 else 的 Patameter 项,这个 Patameter 提供这个在 getSubscribe 为 false 时,将会展现的内容。 在 <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" οnclick="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 。但是我们怎么样才能使 unsubscribe 为 true 的时候 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 的事件已经用于了不同的实现,那么我们该把代码写到哪里?

继续阅读