播放 FormFactory 类型不匹配

Play FormFactory Type Mismatch

我在使用 Scala & Play 时遇到了一些困难。我的模型中有这本书 class

class Book(identifier: Int, title1: String, price1: Int, author1: String) {

  val id: Int = identifier
  val title: String = title1
  var price: Int = price1
  val author: String = author1

  override def toString: String = s" $title written by $author"
}

在我的 BooksController class 中,我定义了基本的 CRUD 操作。我想使用我正在注入的 FormFactory class 做一些魔术。

import javax.inject._
import play.api.mvc._
import model.Book
import model.BookSet
import play.data._
import scala.collection.mutable.HashMap


@Singleton
class BooksController @Inject()(cc: ControllerComponents, formFactory: FormFactory)  (implicit assetsFinder: AssetsFinder)
    extends AbstractController(cc) {

  //show a form
  def create = {
    val bookform: Form[Book] = formFactory.form(classOf[Book])
    Ok(views.html.bookstore.create(bookform))

  }

  //show all books
  def index = Action {
    val map: HashMap[Int, Book] = BookSet.bookMap
    Ok(views.html.bookstore.bookindex(map))
  }

这是我的bookstore.createscala.html文件

@import model.Book
@import helper._

@(bookForm: Form[Book])

<html>
    <head>
        <title>Create Book </title>
    </head>
    <body>
        <h1> Create Book</h1>
        @helper.form( action = routes.BooksController.save() ){
            @helper.inputText(bookForm("id"))
            @helper.inputText(bookForm("title"))
            @helper.inputText(bookForm("price"))
            @helper.inputText(bookForm("author"))

            <input type="submit" value="Create Book">

        }
    </body>

</html>

这些是麻烦的代码行:

val bookform: Form[Book] = formFactory.form(classOf[Book])
Ok(views.html.bookstore.create(bookform))

在第二行,IntelliJ 告诉我 类型不匹配,预期 play.api.data.Form[model.Book],实际 play.data.Form[model.Book]

我尝试通过将以下行添加到 html 来解决此问题,但它会导致错误(可能是由助手 class 引起的)

@import play.data.Form

我也试过使用 asInstanceOf[]:

从工厂传递 play.api.data.Form
val bookform: Form[Book] = formFactory.form(classOf[Book])

Ok(views.html.bookstore.create(bookform.asInstanceOf[play.api.data.Form[Book]]))

在尝试这个之后我在编译过程中得到了错误: 未找到隐式 MessagesProvider 实例。 P 租见 https://www.playframework.com/documentation/2.6.x/ScalaForms#Passing-MessagesProvider-to-Form-Helpers [错误] @helper.inputText(bookForm("title"))

它基本上对每个字段都重复。因此,我遵循了 scala 文档选项 2,并向控制器添加了注入和隐式请求以及对 html 文件的隐式请求。仍然出现相同的错误

在这一点上我感到无助,所以我才问这个问题。 use play.data.FormFactory 真的可以和 helper class 一起使用吗?不幸的是 play.api.data 包没有提供它自己的 FormFactory。我觉得我只是缺少一个明显的解决方案。 感谢耐心等待

我认为乍一看,FormFactory 从来没有为 Scala 而设计,只有 Java。我可能是错的,但我从未在 Scala 中使用过它。

如果您愿意尝试以下方法,您可能会更轻松:

将您的 Book 简单地更改为:

case class Book(identifier: Int, title: String, price: Int, author: String)

创建如下所示的表单:

val bookForm = Form(
   mapping(
     "id" -> number,
     "title" -> nonEmptyText,
     "price" -> number,
     "author" -> nonEmptyText
   )(Book.apply)(Book.unapply)
 )

那么您的 Controller 可能如下所示:

@Singleton
class BooksController @Inject()(cc: ControllerComponents)  
  (implicit assetsFinder: AssetsFinder)
  extends AbstractController(cc) {

  //show a form
  def create = {
    Ok(views.html.bookstore.create(bookForm))
  }

  //show all books
  def index = Action {
     val map: HashMap[Int, Book] = BookSet.bookMap
     Ok(views.html.bookstore.bookindex(map))
  }
}

这里不确定AssetsFinder,但你可能有理由,所以我把它留在了例子中。 ;)