• PLAY2.6-SCALA(十二) 表单的处理


    一、表单处理流程如下

    1.定义一个表单,在这里表单最多有22个字段

    import play.api.data._
    import play.api.data.Forms._
    //要使用验证和约束
    import play.api.data.validation.Constraints._
    
    case class UserData(name: String, age: Int)
    
    val userForm = Form(
      mapping(
        "name" -> text,
        "age" -> number
      )(UserData.apply)(UserData.unapply)
    )
    

    UserData给定Map时,表单将使用绑定值创建实例:

    val anyData = Map("name" -> "bob", "age" -> "21")
    val userData = userForm.bind(anyData).get
    

    但大多数情况下,都会使用Action中的表单和请求中提供的数据。Form包含的bindFromRequest把请求作为一个隐式参数。如果你定义了一个隐含的请求,那么bindFromRequest会发现它。

    val userData = userForm.bindFromRequest.get
    

    get这里使用有一个问题。如果表单无法绑定到数据,get则会抛出异常。在接下来的几节中,我们将展示一种处理输入的更安全的方法。

    2.在表单上添加约束

    name字段不为空

    val userFormConstraints2 = Form(
      mapping(
        "name" -> nonEmptyText,
        "age" -> number(min = 0, max = 100)
      )(UserData.apply)(UserData.unapply)
    )
    

    如果表单的输入与约束不匹配,则使用此表单将导致出现错误的表单:

    val boundForm = userFormConstraints2.bind(Map("bob" -> "", "age" -> "25"))
    //boundForm.hasErrors must beTrue
    

    开箱即用的约束定义在Form对象里

    • text:映射到scala.String,可选地minLengthmaxLength
    • nonEmptyText:映射到scala.String,可选地minLengthmaxLength
    • number:映射到scala.Int,任选需要minmaxstrict
    • longNumber:映射到scala.Long,任选需要minmaxstrict
    • bigDecimal:需要precisionscale
    • datesqlDate:映射到java.util.Datejava.sql.Date任选取patterntimeZone
    • emailscala.String使用电子邮件正则表达式映射到
    • boolean:映射到scala.Boolean
    • checked:映射到scala.Boolean
    • optional:映射到scala.Option

    3.在Action中验证表单

    用fold验证操作中的表单,并处理错误的表单

    userForm.bindFromRequest.fold(
      formWithErrors => {
        // binding failure, you retrieve the form containing errors:
        BadRequest(views.html.user(formWithErrors))
      },
      userData => {
        /* binding success, you get the actual value. */
        val newUser = models.User(userData.name, userData.age)
        val id = models.User.create(newUser)
        Redirect(routes.Application.home(id))
      }
    )
    

    当使用flashing方法或其他方法在flash的域内时,请求过后要重定向,因为重定向到http请求后,新的cookie才可用。

    或者可以使用parse.form将请求的内容绑定到你的表格

    val userPost = Action(parse.form(userForm)) { implicit request =>
      val userData = request.body
      val newUser = models.User(userData.name, userData.age)
      val id = models.User.create(newUser)
      Redirect(routes.Application.home(id))
    }
    

    在失败的情况下,默认行为是返回一个空的BadRequest响应。也可以用自己的逻辑覆盖此行为。例如,下面的代码完全等价于前面使用的bindFromRequestfold

    val userPostWithErrors = Action(parse.form(userForm, onErrors = (formWithErrors: Form[UserData]) => {
      implicit val messages = messagesApi.preferred(Seq(Lang.defaultLang))
      BadRequest(views.html.user(formWithErrors))
    })) { implicit request =>
      val userData = request.body
      val newUser = models.User(userData.name, userData.age)
      val id = models.User.create(newUser)
      Redirect(routes.Application.home(id))
    }
    

    4.在视图模板中显示表单

    未完待续

  • 相关阅读:
    linux命令大全
    linux几个常用命令
    linux基础入门命令自我总结——乱
    linux标准目录的结构——各个目录都是干啥的
    python基础知识9——模块2——常见内置模块
    python基础知识8——模块1——自定义模块和第三方开源模块
    手写数据结构-链表
    手写数据结构-基于动态数组的循环队列
    手写数据结构-基于动态数组的队列
    手写数据结构-基于动态数组的栈
  • 原文地址:https://www.cnblogs.com/feiyumo/p/9151669.html
Copyright © 2020-2023  润新知