Być może właśnie przeoczyłem coś oczywistego, ale nie mogę wymyślić, jak powiązać pole formularza do podwójnego kontrolera Play.Grać: Związać pole formularza z podwójnym?
Na przykład załóżmy, że jest to mój model:
case class SavingsGoal(
timeframeInMonths: Option[Int],
amount: Double,
name: String
)
(Ignoruj że używam podwójne ceny do jakości, wiem, że to zły pomysł, to tylko uproszczony przykład)
i chciałem związać go tak:
object SavingsGoals extends Controller {
val savingsForm: Form[SavingsGoal] = Form(
mapping(
"timeframeInMonths" -> optional(number.verifying(min(0))),
"amount" -> of[Double],
"name" -> nonEmptyText
)(SavingsGoal.apply)(SavingsGoal.unapply)
)
}
zdałem sobie sprawę, że number
pomocnik działa tylko wskazówki, ale myślałem, używając of[]
może pozwolić mi zobowiązywanie podwójne. Jednakże pojawia się błąd kompilatora na ten temat:
Cannot find Formatter type class for Double. Perhaps you will need to import
play.api.data.format.Formats._
Robi tak nie pomaga, jak nie ma podwójne formater zdefiniowane w API.
To wszystko jest tylko długim pytaniem, jaki jest kanoniczny sposób wiązania pola formularza do podwójnej gry?
Dzięki!
edytuj: 4e6 wskazał mi właściwy kierunek. Oto co zrobiłem używając jego pomocy:
Wykorzystując fragmenty w swoim linku, dodałem następujące do app.controllers.Global.scala:
object Global {
/**
* Default formatter for the `Double` type.
*/
implicit def doubleFormat: Formatter[Double] = new Formatter[Double] {
override val format = Some("format.real", Nil)
def bind(key: String, data: Map[String, String]) =
parsing(_.toDouble, "error.real", Nil)(key, data)
def unbind(key: String, value: Double) = Map(key -> value.toString)
}
/**
* Helper for formatters binders
* @param parse Function parsing a String value into a T value, throwing an exception in case of failure
* @param error Error to set in case of parsing failure
* @param key Key name of the field to parse
* @param data Field data
*/
private def parsing[T](parse: String => T, errMsg: String, errArgs: Seq[Any])(key: String, data: Map[String, String]): Either[Seq[FormError], T] = {
stringFormat.bind(key, data).right.flatMap { s =>
util.control.Exception.allCatch[T]
.either(parse(s))
.left.map(e => Seq(FormError(key, errMsg, errArgs)))
}
}
}
Następnie w moim formularzu mapowania:
mapping(
"amount" -> of(Global.doubleFormat)
)
Dzięki! To działa idealnie. Zaktualizuję moje oryginalne pytanie za pomocą mojego rozwiązania na wypadek, gdyby ktoś inny natknął się na to. – Ryan
W chwili pisania tego, link do 'doubleFormat' jest tutaj https://github.com/playframework/playframework/blob/b7c414ef11a1a8befa0caa8dbc52fa4e11128a08/framework/src/play/src/main/scala/play/api/data/format/ Format.scala # L132 (Wskazówka dla profesjonalisty: naciśnij "y" w github, aby uzyskać permalink przywiązany do konkretnego zatwierdzenia. Ponieważ "wzorzec" przesuwa się w czasie, łącza oparte na wzorcu gniją w czasie). –