技术开发 频道

Tapestry表单输入与验证,表单数据失败

    在请求间保存数据

    因为其他的动作请求,表单提交的结果会向客户端发出一个重定向来重新呈现页面。验证跟踪器必须在请求间被持久化地(persistently)保存下来,否则所有的验证信息会丢失(表单提供一个persisten形式的默认验证跟踪器)。

    同样地,组件更新单独的表单域也应该被持久化。

    比如,一个用来收集用户名与密码的登录页面,应该如下:
public class Login { @Persist private String _userName; private String _password; @Inject private UserAuthenticator _authenticator; @Component(id = "password") private PasswordField _passwordField; @Component private Form _form; String onSuccess() { if (!_authenticator.isValid(_userName, _password)) { _form.recordError(_passwordField, "Invalid user name or password."); return null; } return "PostLogin"; } public String getPassword() { return _password; } public void setPassword(String password) { _password = password; } public String getUserName() { return _userName; } public void setUserName(String userName) { _userName = userName; } }
    因为Form表单提交实际上是两个请求(提交自己,然后重新呈现页面),所以需要在两个请求间持久化保存在_userName属性里的值。属性_password同样需要,除非PasswordField组件从不呈现值。

    注意onSuccess()方法不是公共的(public);事件处理方法可以具有任何的可见性,甚至私有的。包可见性(即无可见性修饰)比较常用,这时它允许组件可被相同包下的测试用例类测试。

    假如Form先前没有存在验证错误,它仅产生一个"success"事件,这意味着没有必要在方法的第一行写上if (_form.getHasErrors()) return;这样的语句。

    最后,注意业务逻辑如何与表单验证相关联。UserAuthenticator服务用来保证userName 和 (文本的) password的有效性。当它返回false时,我们用Form组件来记录一个错误。我们提供一个PasswordField实例作为它的第一个参数,这保证了密码表单域和它的标注(label)会在Form表单重新呈现时被修饰以表现错误给用户看。

    配置表单域及标注

    页面模板包含少量的Tapestry 标识(instrumentation):
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd"> <head> <title>Login</title> </head> <body> <h1>Please Login</h1> <t:form> <t:errors/> <t:label for="userName"/>: <input t:type="TextField" t:id="userName" t:validate="required,minlength=3" size="30"/> <br/> <t:label for="password"/>: <input t:type="PasswordField" t:id="password" t:validate="required,minlength=3" size="30"/> <br/> <input type="submit" value="Login"/> </t:form> </body> </html>
    Tapestry的Form组件负责创建form表单提交所需的URL(这个Tapestry的责任,不是你的)。

    Errors组件必须放在Form里,它将Form组件里表单域的所有错误信息作为一个列表输出,并应用一此简单的样式使得结果更显眼。

    每一个表单域组件,比如TextField,与Label组件成对。Label将呈现一个与表单域相连的<label>元素。这个组件对方便使用非常重要,特别对那些有视觉障碍(残疾)的用户。它意味着你可以能过点击标注(label)文本将光标移动到相应的表单域中。

    Label组件的for参数即是一组件的id。

    对于TextField,我们提供了一个组件id为userName。我们可以指定一个value参数,默认情况下这个value参数是匹配TextField的id,TextField的id又对应于组件容器(Login页)的一个属性(假如这个属性存在)。

    根据经验,你通常应该为表单域指定一个特定的id(这个id将会被用来呈现标签的name与id属性)。允许省略value参数有利于防止模板变得更加混乱。

    用来验证表单域的validate参数标识,是一个验证器的名字列表。验证器在Tapestry中被配置,可用的验证器都是可扩展的。"required"是一个内置验证器的名字,用以保证提交的值不为空串,此外,"minlen"用来保证值具有最小的指定长度。

    Validate参数用t:前缀被放置在Tapestry的命名空间里。这不是严格需要的,只是让模板有个良好的格式。然而,在Tapestry命名空间放置Tapestry特定的值保证了模板的有效性。
0
相关文章