这是对复杂表单问题的跟进:How to get child record (case class) ID in Play Framework (2.4.0) using Forms
lazy val aForm = Form(
mapping(
"ID" -> ignored(id),
"firstName" -> nonEmptyText,
"lastName" -> nonEmptyText,
"listOfEmails" -> mapping(
"ID" -> ignored(emailID),
"email" -> email,
"userID" -> ignored(id),
"emailTypeID" -> longNumber)
(UserEmail.apply)(UserEmail.unapply) verifying someConstraint,
"statusID" -> ignored(0l),
"roleID" -> default(longNumber, roleID),
"timezoneID" -> default(longNumber, timezoneID)
(User.apply)
(User.unapply)
)
现在由于约束在 apply
方法之后,我们有转换后的 case class
并访问它的所有字段,因此我们可以编写一个使用来自的数据的验证任何和所有领域。不确定我是否真的对此感到满意 - 为什么在测试前转换数据 - 为什么我们不能简单地使用手头已有的数据进行验证过程?如果 case class
本身由于错误的数据或内部验证过程而在创建过程中出现任何异常,这也会带来问题,但这将是一个足够小的角落案例,可以为 - 自定义 case class
仅用于验证。
def someConstraint: Constraint[UserEmail] = Constraint("constraints.unique")({
userEmail =>
match doStuff(userEmail.ID, userEmail.email, userEmail. emailTypeID) {
case BAD => Invalid(Seq(ValidationError("error.unique.email.required")))
case GOOD => Valid
}
}
|)
对于伪代码,我们深表歉意,但希望您对验证过程中发生的事情有基本的了解。我们取几个字段并处理它们包含的数据以进行验证判断调用。
事情是这样的。
在 HTML 输出中,嵌套类字段必须引用为:listOfEmails[x].ID
和 listOfEmails[x].email
等,以便播放在 POST
上正确捕获它们的框架 -- https://www.playframework.com/documentation/2.4.0/ScalaForms
然而,约束过程返回 listOfEmails[x]
作为错误键的字段名称,因此它不会出现在 html 模板中,因为该键不匹配任何内容。
那么如何重命名错误字段键(假设这是这里的正确答案)或者一个更好的问题是如何端到端地播放这个过程?
是的,我们可以使用全局错误,但是在大型复杂的表单上,我们希望获得尽可能接近解决方案的错误,以便用户的眼球能够快速捕捉并向前移动。
最佳答案
object TestSeq extends App {
//case class Email(email: String)
case class Email(email: String,f1:String,f2:String,f3:String,f4:String,f5:String,f6:String,f7:String,f8:String,f9:String)
case class User(name: String, emails: Seq[Email], addr: String)
import play.api.data.Forms._
import play.api.data._
import play.api.data.validation._
val someConstraint: Constraint[Email] =
Constraint("constraints.unique"){ email =>
if(email.email.contains('@')) Valid
else Invalid(ValidationError("error.unique.email.required"))
}
val form = Form(
mapping(
"name" -> text,
"emails" -> seq(mapping(
"email" -> nonEmptyText,
"f1" -> text,
"f2" -> text,
"f3" -> text,
"f4" -> text,
"f5" -> text,
"f6" -> text,
"f7" -> text,
"f8" -> text,
"f9" -> text
)(Email.apply)(Email.unapply) verifying someConstraint),
"addr" -> text
)(User.apply)(User.unapply)
)
val data = Map[String, String](
"name" -> "xx",
"emails[0].email" -> "a0@xx.com",
"emails[0].f1" -> "0f1",
"emails[0].f2" -> "0f2",
"emails[0].f3" -> "0f3",
"emails[0].f4" -> "0f4",
"emails[0].f5" -> "0f5",
"emails[0].f6" -> "0f6",
"emails[0].f7" -> "0f7",
"emails[0].f8" -> "0f8",
// "emails[0].f9" -> "0f9",
"emails[1].email" -> "",
"emails[1].f1" -> "1f1",
"emails[1].f2" -> "1f2",
"emails[1].f3" -> "1f3",
"emails[1].f4" -> "1f4",
"emails[1].f5" -> "1f5",
"emails[1].f6" -> "1f6",
"emails[1].f7" -> "1f7",
"emails[1].f8" -> "1f8",
"emails[1].f9" -> "1f9",
"emails[2].email" -> "a2xx.com",
"emails[2].f1" -> "2f1",
"emails[2].f2" -> "2f2",
"emails[2].f3" -> "2f3",
"emails[2].f4" -> "2f4",
"emails[2].f5" -> "2f5",
"emails[2].f6" -> "2f6",
"emails[2].f7" -> "2f7",
"emails[2].f8" -> "2f8",
"emails[2].f9" -> "2f9",
"addr" -> "dalian"
)
val user = form.bind(data).fold(
ef => ef.errors.foreach(println _) ,
contact =>println(contact)
)
/* ===== output =====
FormError(emails[0].f9,List(error.required),List())
FormError(emails[1].email,List(error.required),WrappedArray())
FormError(emails[2],List(error.unique.email.required),WrappedArray())
user: Unit = ()
*/
}
关于forms - In Play 2.4.0 如何在嵌套表单的多字段约束中命名字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30710707/