如何将枚举绑定到playframework表单?

时间:2017-07-22 22:14:49

标签: scala playframework

我有一个形式的枚举:

object MatchFilterType extends Enumeration {
  type MatchFilterType = Value
  val gt = Value("gt")
  val lt = Value("lt")
  val eq = Value("eq")
}

尝试在我的控制器中创建表单val:

 case class SearchRequest(mft: MatchFilterType, queryText: String, locations: List[String])

 val searchForm: Form[SearchRequest] = Form(
    mapping(
      "mft" -> ????????,
      "queryText" -> nonEmptyText,
      "locations" -> list(text)
    )(SearchRequest.apply)(SearchRequest.unapply)
  )

我在这个项目中使用了2.6.x版。

如何在我的Form val中映射枚举?

2 个答案:

答案 0 :(得分:2)

首先创建一个使用枚举Formatter方法的隐式withName,该方法接受一个字符串并将其转换为枚举:

implicit def matchFilterFormat: Formatter[MatchFilterType] = new Formatter[MatchFilterType] {

  override def bind(key: String, data: Map[String, String]) =
    data.get(key)
        .map(MatchFilterType.withName(_))
        .toRight(Seq(FormError(key, "error.required", Nil)))

  override def unbind(key: String, value: MatchFilterType) = 
    Map(key -> value.toString)
}

然后使用Forms.of创建FieldMapping

Form(...,
     "mft" -> Forms.of[MatchFilterType],
     ...)

请记住,如果字符串不是枚举成员,MatchFilterType.withName(_)将抛出异常,因此请更新bind方法以根据需要处理此问题。

答案 1 :(得分:1)

更通用的方法:

def enumerationFormatter[E <: Enumeration](enum: E): Formatter[E#Value] = new Formatter[E#Value] {
  override def bind(key: String, data: Map[String, String]): Either[Seq[FormError], E#Value] =
    data.get(key).map(s => enum.withName(s)).toRight(Seq(FormError(key, "error.required", Nil)))
  override def unbind(key: String, value: E#Value): Map[String, String] = Map(key -> value.toString)
}

然后可以这样使用:

object TestValues extends Enumeration {
  type TestValue = Value
  val Test: TestValue = Value
}
case class MyForm(testValue: TestValue)
object MyForm {
  implicit val testValueFormatter: Formatter[TestValue] = enumerationFormatter(TestValues)
  val form = Form(mapping("testValue" -> of[TestValue])(MyForm.apply)(MyForm.unapply))
}