2012-10-06 16 views
10

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) 
) 

Odpowiedz

10

W rzeczywistości, there is predefiniowany formater dla Double na gałęzi głównej. Więc powinieneś albo przełączyć się do wersji 2.1-SNAPSHOT albo po prostu skopiować implementację.

+0

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

+0

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). –

11

Nie musisz używać formatu w wersji globalnej, jeśli masz wersję 2.1 w górę.

Tylko import:

import play.api.data.format.Formats._ 

i używać jako:

mapping(
    "amount" -> of(doubleFormat) 
) 
Powiązane problemy