如果表单字段有多个验证器,如何让它们逐个验证它们,而不是全部?

Fre*_*ind 2 validation playframework-2.0

我有一个登录表单,有一个name输入有很多验证器:

object Users extends Controller {

    val loginForm = Form(tuple(
        "name" -> ( 
            nonEmptyText // (1)
            verifying ("Its length should >= 4", name=>{ println("#222");name.length>=4 }) // (2)
            verifying ("It should have numbers and letters", name=>{println("#333"); ...}) // (3)
        )
}
Run Code Online (Sandbox Code Playgroud)

然后我不输入任何内容,按提交,我发现控制台打印:

#222
#333
Run Code Online (Sandbox Code Playgroud)

这意味着所有验证器都已执行,并且它们之间存在关系

(1) & (2) & (3)
Run Code Online (Sandbox Code Playgroud)

但我希望他们:

(1) && (2) && (3)
Run Code Online (Sandbox Code Playgroud)

这意味着,如果名称为空,则后两个验证器将被忽略.

在play2中有可能吗?

Jul*_*Foy 5

默认行为是应用在字段上定义的所有约束.但是,您可以定义自己的验证约束,以停止对第一个失败应用约束:

def stopOnFirstFail[T](constraints: Constraint[T]*) = Constraint { field: T =>
  constraints.toList dropWhile (_(field) == Valid) match {
    case Nil => Valid
    case constraint :: _ => constraint(field)
  }
}
Run Code Online (Sandbox Code Playgroud)

它可以像下面这样使用:

val loginForm = Form(
  "name" -> (text verifying stopOnFirstFail(
    nonEmpty,
    minLength(4)
  ))
)
Run Code Online (Sandbox Code Playgroud)
scala> loginForm.bind(Map("name"->"")).errors
res2: Seq[play.api.data.FormError] = List(FormError(name,error.required,WrappedArray()))

scala> loginForm.bind(Map("name"->"foo")).errors
res3: Seq[play.api.data.FormError] = List(FormError(name,error.minLength,WrappedArray(4)))

scala> loginForm.bind(Map("name"->"foobar")).errors
res4: Seq[play.api.data.FormError] = List()
Run Code Online (Sandbox Code Playgroud)

(注意我的实现stopOnFirstFail应用了两次失败的约束,所以这个应该没有副作用)