我正在使用Scala-Play 2.5.x并且需要定义一个需要映射的枚举类型的表单,即
object OptionType extends Enumeration {
type Type = Value
val Call = Value("Call")
val Put = Value("Put")
val Straddle = Value("Straddle")
}
case class MyParameters(impliedVolSpread: Double, optionType: OptionType.Type)
@Singleton
class MyForm @Inject()(implicit val messagesApi: MessagesApi) {
val Instance = Form {
mapping(
"impliedVolSpread" -> of[Double],
"optionType" -> of[OptionType.Type],
)(MyParameters.apply)(MyParameters.unapply)
}
}
但这会导致编译错误:
Cannot find Formatter type class for OptionType.Type.
Perhaps you will need to import play.api.data.format.Formats._
在回顾其他类似的问题后,我认为这个用例已经解决,例如Enum Mapper PR 240
答案 0 :(得分:2)
由于PR在Scala-Play 2.5.10中仍然无法使用,我偷了我需要的位并结束了这样的结束:
import play.api.data._
import play.api.data.format._
import play.api.data.Forms._
object EnumPlayUtils {
//------------------------------------------------------------------------
// public
//------------------------------------------------------------------------
/**
* Constructs a simple mapping for a text field (mapped as `scala.Enumeration`)
*
* For example:
* {{{
* Form("gender" -> enum(Gender))
* }}}
*
* @param enum the enumeration
*/
def enum[E <: Enumeration](enum: E): Mapping[E#Value] = of(enumFormat(enum))
/**
* Default formatter for `scala.Enumeration`
*
*/
def enumFormat[E <: Enumeration](enum: E): Formatter[E#Value] = new Formatter[E#Value] {
def bind(key: String, data: Map[String, String]) = {
Formats.stringFormat.bind(key, data).right.flatMap { s =>
scala.util.control.Exception.allCatch[E#Value]
.either(enum.withName(s))
.left.map(e => Seq(FormError(key, "error.enum", Nil)))
}
}
def unbind(key: String, value: E#Value) = Map(key -> value.toString)
}
}
并像这样使用:
@Singleton
class MyForm @Inject()(implicit val messagesApi: MessagesApi) {
import EnumPlayUtils._
val Instance = Form {
mapping(
"impliedVolSpread" -> of[Double],
"optionType" -> enum(OptionType),
)(MyParameters.apply)(MyParameters.unapply)
}
}