本文介绍了播放:将表单字段绑定到双打吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

也许我只是忽略了一些明显的东西,但是我不知道如何在Play控制器中将表单字段绑定到double上.

Perhaps I'm just overlooking something obvious but I can't figure out how to bind a form field to a double in a Play controller.

例如,假设这是我的模型:

For instance, assume this is my model:

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

(忽略我使用的是双重支付功能,我知道这是一个坏主意,这只是一个简化的示例)

(Ignore that I'm using a double for money, I know that's a bad idea, this is just a simplified example)

我想像这样绑定它:

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助手仅适用于int,但我认为使用of[]可能会使我绑定双精度型.但是,我在此出现编译器错误:

I realized that the number helper only works for ints but I thought using of[] might allow me to bind a double. However, I get a compiler error on this:

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

这样做没有帮助,因为API中没有定义双重格式化程序.

Doing so doesn't help as there's no double formatter defined in the API.

这只是询问在Play中将表单字段绑定到双打的规范方式的一种很长的方法?

This is all just a long way of asking what's the canonical way of binding a form field to a double in Play?

谢谢!

4e6为我指明了正确的方向.这是我在他的帮助下所做的事情:

edit: 4e6 pointed me in the right direction. Here's what I did using his help:

使用他的链接中的片段,我在app.controllers.Global.scala中添加了以下内容:

Using the snippets in his link, I added the following to 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)))
      }
    }

}

然后,在我的表单映射中:

Then, in my form mapping:

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

推荐答案

实际上,在主分支上有Double预定义的格式化程序.因此,您应该切换到2.1-SNAPSHOT播放版本或仅复制实现.

Actually, there is predefined formatter for Double on master branch. So you should either switch to 2.1-SNAPSHOT play version or just copy the implementation.

这篇关于播放:将表单字段绑定到双打吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

查看更多