首页 > 解决方案 > 创建泛型 Form 函数时不重复参数的扩展

问题描述

我正在尝试创建一个函数,该函数接受可变数量的参数并输出一个将每个参数映射到nonEmptyText.

这是我到目前为止所尝试的:

  1. 映射 args 以创建动态元组(产生多个编译器错误):

    def formBuilder(args: String*): Form[_] = {
      Form(
        tuple(
          args.map(arg => arg -> nonEmptyText):_*
        )
      )
    }
    
  2. 通过映射 args 来创建单曲列表(给出Expansion for non repeated parameter错误):

    def formBuilder(args: String*): Form[_] = {
      Form(
        list(
          args.map(arg => single(arg -> nonEmptyText)): _*
        )
      )
    }
    

我的用例是我正在构建一个前端搜索页面,该页面包含一组基于参数的不同字段,name. 以前,我不需要为此制作表单,因为任何搜索的所有字段都是可选的,但我刚刚收到一些业务规则,其中指出某些names 具有特定的表单规则。因此,当我.bindFromRequest()在此表单上的控制器中执行操作时,如果表单填写不正确,我需要使用这些现已验证的表单中的数据来显示表单错误(与以前我没有费心将表单验证为每个字段都是可选的)。

我希望这是有道理的。让我知道我是否可以进一步澄清。无论如何,这是我到目前为止所获得的完整实现,希望能进一步解释我的问题:

def searchForm(name: String, args: String*): Form[_] = {
  name.toUpperCase() match {
    case NAME_1 => Form(
      tuple(
        NAME_1_FIELD_1 -> nonEmptyText,
        NAME_1_FIELD_2 -> nonEmptyText
      )
    )
    case NAME_2 => Form(
      tuple(
        NAME_2_FIELD_1 -> nonEmptyText,
        NAME_2_FIELD_2 -> optional(text),
        NAME_2_FIELD_3 -> optional(text)
      ).verifying("HELP YOU FAILED", _ match {
        case (_, Some(_), _) | (_, _, Some(_)) => true
        case _ => false
      })
    )
    case _ => formBuilder(args: _*)
  }
}

def formBuilder(args: String*): Form[_] = {
  Form(
    list(
      args.map(arg => single(arg -> optional(text))): _*
    )
  )
}

这就是我希望从我的控制器调用我的表单检查器函数的方式:

searchForm(name, Seq("val1", "val2", "val3")).bindFromRequest().fold(
  // redirect back to previous page with form error warnings  
  formWithErrors => Future.successful(Redirect(.....))),
  // do something with the valid form
  formWithoutErrors => {
    .....
  }
)

我已经为此工作了几个小时,但运气不佳。如何成功创建带有可变参数的表单?

标签: formsscalaplayframework

解决方案


这是不可能的优雅方式。元组包含固定数量的任意类型的元素。List 包含可变数量的相同类型(或公共超类型)的元素。您想要的本质上是将列表转换为元组。

如果您知道元组中的最大元素数(并且不是太大),您可以为每个可能的元素数编写一个匹配项。

元组中元素的数量被限制为一个很小的值(可能是 22)。


推荐阅读