2012-10-06 46 views
10

也許我只是忽略了一些顯而易見的東西,但我無法弄清楚如何將表單字段綁定到Play控制器中的double。玩:綁定一個表單域到雙?

舉例來說,假設這是我的模型:

case class SavingsGoal(
timeframeInMonths: Option[Int], 
amount: Double, 
name: String 
) 

(忽略,我使用了雙要錢,我知道這是一個壞主意,這只是一個簡單的例子)

我想結合它像這樣:

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) 

    ) 

} 

我意識到number助手只適用於整數,但我想用of[]可能讓我綁定雙。不過,我得到一個編譯器錯誤:

Cannot find Formatter type class for Double. Perhaps you will need to import 
play.api.data.format.Formats._ 

這樣做沒有幫助,因爲API中沒有定義雙格式化程序。

這只是一個很長的問題,要求在Play中將表單字段綁定到double的規範方式是什麼?

謝謝!

編輯:4e6指出我在正確的方向。這是我做了使用他的幫助:

用在他的鏈接片段,我增加了以下內容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))) 
     } 
    } 

} 

然後,在我的表格映射:

mapping(
    "amount" -> of(Global.doubleFormat) 
) 

回答

10

實際上,there is在master分支上爲Double預定義格式器。所以你應該切換到2.1-SNAPSHOT播放版本或者只是複製實現。

+0

謝謝!這是完美的。我會用我的解決方案更新我的原始問題,以防其他人絆倒這一點。 – Ryan

+0

在撰寫本文時,指向'doubleFormat'的鏈接位於https://github.com/playframework/playframework/blob/b7c414ef11a1a8befa0caa8dbc52fa4e11128a08/framework/src/play/src/main/scala/play/api/data/format/ Format.scala#L132(專業提示:在github中按「y」以獲得與特定提交綁定的固定鏈接。由於「master」隨時間推移而移動,因此基於主站的鏈接會隨着時間的推移而變質。 –

11

如果您的版本爲2.1,則無需使用全局格式。

只需要導入:

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

和使用:

mapping(
    "amount" -> of(doubleFormat) 
)