这似乎是一个非常基本的问题。我正在使用Play Framework 2.1.5与Scala 2.10开发一个CRUD应用程序(将来会有更多)。我也在使用Twitter Bootstrap 3.2.0。当我尝试更新对象时,我无法获取模板来呈现表单的值。
我正沿着这本书Play for Scala。我已经可以创建一个新对象了。现在我希望能够编辑对象。
Product
域对象使用Squeryl映射:
case class Product(ean: Long, name: String, description: String) extends KeyedEntity[Long]
随附的Person
对象具有相应的CRUD功能。 Product.findByEan(ean)
是一个简单的按字段查询搜索,返回Option[Person]
。
Persons
控制器具有Form[Person]
映射:
private val productForm = Form(mapping(
"ean" -> longNumber.verifying("validation.ean.duplicate", Product.findByEan(_).isEmpty),
"name" -> nonEmptyText,
"description" -> nonEmptyText)(Product.apply)(Product.unapply))
在我的routes
GET /products controllers.Products.list
POST /products controllers.Products.save
GET /products/new controllers.Products.newProduct
GET /products/$ean<\d{13}> controllers.Products.show(ean: Long)
GET /products/$ean<\d{13}>/edit controllers.Products.edit(ean: Long)
Products.edit
路线应使用其ean
字段加载产品,并使用找到的产品预先填写编辑表单。
def edit(ean: Long) = Action { implicit request =>
Product.findByEan(ean) match {
case Some(product) =>
Logger.info("found product: ean = " + ean)
val form = productForm.fill(product)
Logger.info(form.toString)
Ok(views.html.products.editProduct(form))
case None => Redirect(routes.Products.list)
}
}
我知道我已成功检索到该对象,因为Logger
消息在播放控制台中清楚地显示了这一点。
呈现表单的editProducts
模板是:
@(productForm: Form[Product])(implicit flash: Flash, lang: Lang)
@import helper._
@import helper.twitterBootstrap._
@productsLayout(Messages("products.form")) {
<h2>@Messages("products.form")</h2>
@helper.form(action = routes.Products.save()) {
<fieldset>
<legend>
@Messages("products.details", Messages("products.edit"))
</legend>
@helper.inputText(productForm("product.ean"))
@helper.inputText(productForm("product.name"))
@helper.textarea(productForm("product.description"))
</fieldset>
<p><input type="submit" class="btn primary" value='@Messages("products.edit.submit")'</p>
}
}
问题在于,当我尝试编辑我的Product对象时,此表单模板不会使用检索到的产品对象中的<input>
属性预填充value
标记。当我尝试创建一个对象但提交一个包含验证错误的表单时,相同的模板工作正常。
答案 0 :(得分:1)
广告。 1 强>
您的问题与您引用表单字段名称的方式有关。您不应该将映射对象名称作为前缀。
@helper.inputText(productForm("ean"))
@helper.inputText(productForm("name"))
@helper.textarea(productForm("description"))
更多信息
值得记住,通过提供映射中指定的名称来访问表单字段。指定的字段名称不必与相应的案例类字段名称匹配。如果您的映射看起来像这样
private val productForm = Form(mapping(
"id" -> longNumber.verifying("validation.ean.duplicate", Product.findByEan(_).isEmpty),
"full-name" -> nonEmptyText,
"desc" -> nonEmptyText)(Product.apply)(Product.unapply))
您可以通过这种方式访问模板中的字段
@helper.inputText(productForm("id"))
@helper.inputText(productForm("full-name"))
@helper.textarea(productForm("desc"))
广告。 2 强>
虽然如果您点击 Twitter引导程序字段构造函数部分中的 Twitter Bootstrap 链接,字段帮助程序工作正常,您将被重定向到Bootstrap v2.3.2主页,我想这个助手是为以前的版本设计的。
http://www.playframework.com/documentation/2.1.x/JavaFormHelpers
此外,我建议阅读 Play 2.3迁移指南中的Bootstrap部分,该部分解释了为什么要删除Bootstrap的内置支持。您应该考虑为最新的Bootstrap版本创建自定义字段助手。如果您考虑迁移到较新版本的Play框架,它将减轻您的痛苦。