3

因此,对于我正在开发的系统,我正在尝试做类似的事情:

如果我有一个名为 User 的模型,它有一个 _id (ObjectId)、用户名、密码,然后我正在尝试创建一个新约会,我的表单将查找患者(在下拉列表中显示患者姓名,但实际上会选择病人的 ObjectId)和预约时间。

现在我到处找,找不到任何接近我想要达到的解决方案的东西。

在 Application.scala 中,我有:

val appointmentForm= Form(
  tuple(
    "patient" -> nonEmptyText, // ObjectId
    "startTime" -> nonEmptyText))

我不确定如何充分发挥我的观点以反映患者。我知道你必须做这样的事情:

@select(appointmentForm("patient"), options(..)

谁能给我任何关于如何查找此示例的患者以获取 Mongo ObjectId 的想法。

顺便说一句,我使用的 ORM 是https://github.com/leon/play-salat

4

2 回答 2

1

这是一个示例,我将如何做到这一点:

路线:

GET      /test        controllers.Test.show
POST     /test        controllers.Test.submit

看法:

@(f: Form[(ObjectId, String)], users: Seq[(ObjectId, String)])
@import helper._

@form(action = routes.Test.submit) {
  @select(f("patient"), options = users.map(user => (user._1.toString, user._2)))
  @inputText(f("startTime"))
  <input type="submit" value="Submit!">
}

控制器:

package controllers

import org.bson.types.ObjectId
import play.api.data.format.Formatter
import play.api.mvc._
import play.api.data.Forms._
import play.api.data._
import play.api.data.FormError
import play.api.Logger

object Test extends Controller {

  /**
   * Converts an ObjectId to a String and vice versa
   */
  implicit object ObjectIdFormatter extends Formatter[ObjectId] {
    def bind(key: String, data: Map[String, String]) = {
      val error = FormError(key, "error.required.ObjectId", Nil)
      val s = Seq(error)
      val k = data.get(key)
      k.toRight(s).right.flatMap {
        case str: String if (str.length() > 0) => Right(new ObjectId(str))
        case _ => Left(s)
      }
    }
    def unbind(key: String, value: ObjectId) = Map(key -> value.toStringMongod())

    val objectId: Mapping[ObjectId] = of[ObjectId]
  }

  // import to get objectId into scope
  import ObjectIdFormatter._

  // define user tuples consisting of username and ObjectId for the dropdown. In real lif the list is probably fetched from the db
  def users: Seq[(ObjectId, String)] =
    Seq((new ObjectId("4f456bf744aed129d04db1bd"), "dieter"), (new ObjectId("4faa410b44aec5a0a980599f"), "eva"))

  val appointmentForm= Form(
    tuple(
      "patient" -> objectId, // use the ObjectIdFormatter
      "startTime" -> nonEmptyText))


  def show = Action {
    Ok(views.html.test(appointmentForm, users))
  }

  def submit = Action { implicit request =>
    appointmentForm.bindFromRequest.fold(
      formWithErrors => {
        Logger.warn("errors: " + formWithErrors.errors)
        BadRequest(views.html.test(formWithErrors, users))
      },
      formContent => {
        Logger.info("formContent: " + formContent)
        Ok(views.html.test(appointmentForm, users))
      })
  }
}
于 2012-09-11T14:30:41.323 回答
0

仅供参考,在看到 maxmc 的这篇精彩评论后,我终于解决了这个问题。事实证明,我的问题确实是一个基本的 scala 问题。我没有意识到 List 是 Seq 的实现。所以使用 Mongo,在这个例子中,你要做的就是在你的代码中如下:

控制器

 def newAppointment= Action {
   val pList  = Patient.findAll.toList
   Ok(views.html.admin.newuser(appointmentForm, pList))
 }

看法:

@(appointmentForm: Form[(String, String, String)], pList : List[Patient])

…………

@select(
        appointmentForm("patient"),
        pList.map{ p =>
            p.id.toString -> (p.patientName)
        },
        '_default -> "--- Select a Patient ---",
        '_label -> "Patient"
    )

Model.findAll 函数返回 Iterator[Type]。我们不希望那样。我们需要检索一个可以在视图内遍历的列表。这就是你这样做的原因 findAll.toList 。从那里,@select 将映射 pList,并且数据库中的每个条目的 id 都与患者姓名相关联。注意它是一个字符串,因为@Select 标签的 Seq 需要 Seq(String, String)

于 2012-11-05T19:09:03.027 回答