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

表单输入与验证
 
表单输入是任何应用的生命之血;这是一种从用户收集有用信息的最有效的方式。不管它是一个搜索表单、一个登录还是一个多页的注册向导,用户借助表单在应用中真正地表达他们。
 
Tapestry 在创建表单和验证输入有很好的表现。输入验证是声明式的,意味首我们简单地告诉 Tapestry 一个表单域应用哪种验证,然后 Tapestry 会在服务器端(已实现)与客户端维护这种验证。
 
最后, Tapestry 不仅能够将错误的信息表现给用户,而且还能对表单域及其标注( labels )进行装饰,标记它们包含错误(主要利用 CSS 效果)。
 
表单组件
 
Tapestry 的表单支持的核心即是表单组件,表单组件封装着其他所有表单域组件,如 TextFieldTextAreaCheckbox 等等。
 
表单组件产生许多组件事件,我们可以给其提供事件处理方法。
 
呈现时,表单组件发出一个“ prepare ”通知,以使表单容器创建将要在表单中引用的表单域或属性。如,这是一个创建被呈现的临时实体对像或者载入一个源自数据库的可被编辑的实体的好机会。
 
当用户在客户端提交表单时,服务器端会执行一系列的步骤。
 
首先,表单呈现时会发出一个“ prepare ”通知。
 
其次,所有的表单域被激活并将从请求中得到相应的值,验证它们及(如果有效)保存现有的变化。
 
Tapestry 4 的用户: Tapestry 5 不使用 Tapestry 4 中 脆弱的表单刷新( form rewind )方法,而是在表单呈现时产生一个存放是否需要处理表单提交信息的隐藏域。
 
表单域流程处理完后,表单发出一个“ validate ”事件,这是一个执行跨表单验证(还不能公布其详情)的机会。
 
然后,表单确定是否存在任何验证错误。如果存在,表单提交失败并发出一个 "failure" 事件。如果没有验证错误,些时将 发出 一个 "success" 事件。
 
最后,表单发出一个 "submit" 事件(逻辑上,它不考虑成功与否)。
 
跟踪验证错误
 
一个与表单关联的就是验证跟踪器( ValidationTracker ),它跟踪着表单域对应的所有的用户输入与用户验证错误。跟踪器可以通过跟踪器参数提供给表单,不过很少用到。
 
表单( Form )包括两个 isValid() getHasErrors() 方法,用来查看表单验证跟踪器是否存在任何错误。
 
在我们的逻辑中,我们可以记录验证错误。表单( Form )包括两个不同版本的 recordError() 方法,一个是指定一个表单域( Field ,一个被所有表单元素组件实现的接口),另外一个是全局验证错误( "global" errors ),与具体的表单域无关。
 
在请求间保存数据
 
因为其他的动作请求,表单提交的结果会向客户端发出一个重定向来重新呈现页面。验证跟踪器必须在请求间被持久化地( 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
        titleLogin/title
    /head
    body
        h1Please 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
 
TapestryForm 组件负责创建 form 表单提交所需的 URL (这个 Tapestry 的责任,不是你的)。
 
Errors 组件必须放在 Form 里,它将 Form 组件里表单域的所有错误信息作为一个列表输出,并应用一此简单的样式使得结果更显眼。
 
每一个表单域组件,比如 TextField ,与 Label 组件成对。 Label 将呈现一个与表单域相连的 < label >元素。这个组件对方便使用非常重要,特别对那些有视觉障碍(残疾)的用户。它意味着你可以能过点击标注( label )文本将光标移动到相应的表单域中。
 
Label 组件的 for 参数即是一组件的 id
 
对于 TextField ,我们提供了一个组件 id 为 userName 。我们可以指定一个 value 参数,默认情况下这个 value 参数是匹配 TextFieldidTextFieldid 又对 应于组 件容器( Login 页)的一个属性(假如这个属性存在)。
 
根据经验,你通常应该为表单域指定一个特定的 id (这个 id 将会被用来呈现标签的 nameid 属性)。允许省略 value 参数有利于防止模板变得更加混乱。
 
用来验证表单域的 validate 参数标识,是一个验证器的名字列表。验证器在 Tapestry 中被配置,可用的验证器都是可扩展的。 "required" 是一个内置验证器的名字,用以保证提交的值不为空串,此外, "minlen" 用来保证值具有最小的指定长度。
 
Validate 参数用 t: 前缀被放置在 Tapestry 的命名空间里。这不是严格需要的,只是让模板有个良好的格式。然而,在 Tapestry 命名空间放置 Tapestry 特定的值保证了模板的有效性。
 
错误及修饰Errors and Decorations
 
注意:这部分并没有更新到涉及客户端验证的介绍。
 
当你第一次激活 Login 页里,表单域及表单会被正常呈现等待输入:
 
 
注意这里的 Label 组件怎样显示表单域的文本名字。我们未曾做过任何显式地配置,组件的 id "User Name" "Password" )已经转换成 "User Name" "Password" ,倒底发生了什么?。
 
如果你就这样提交了表单,表单域就会违反了 "required" 约束,页面将会重新显示以呈现给用户错误信息:
 
 
 
这里有两个微妙事情,首先, Tapestry 跟踪了所有表单域的所有错误信息, Errors 组件显示在表单的最顶端;其次,默认的验证修饰给标注( labels )和表单域的 class 属性加上了 t-error CSS 样式。 Tapestry 提供了默认的 t-error CSS 样式使得它们变红。
 
接下来,我们将在 user name 栏上填值,但不给 password 栏提供足够的字符:
 
 
User name 栏正常,仅 password 栏有一个错误存在。 PasswordField 组件默认下通常显示一空值,另外我们会看到仅 password 显示在 …
 
如果你输入了足够的字符后提交,我们会看到 Login 页面是如何将逻辑错误加入到表单域的错误里:
 
这真是天衣无缝,基于应用的逻辑错误看起来感觉就像内置验证器的行为。
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值