将参数传递给grails表单
我是grails新手,我正在尝试将对象Id传递给表单。我有一个叫做啤酒和食谱的域名。啤酒有许多配方,配方属于啤酒。我想从啤酒秀页面创建一个指向新配方的链接,在url中传递啤酒id,以便创建关联。目前,我一直在尝试使用此链接将参数传递给grails表单,grails,gsp,Grails,Gsp,我是grails新手,我正在尝试将对象Id传递给表单。我有一个叫做啤酒和食谱的域名。啤酒有许多配方,配方属于啤酒。我想从啤酒秀页面创建一个指向新配方的链接,在url中传递啤酒id,以便创建关联。目前,我一直在尝试使用此链接创建配方,并在表单中检索它作为隐藏字段,以便使用与配方表单一起提交(我知道未设置隐藏属性)。我做错了什么?还有没有更好的方法来创建此关联 啤酒领域类 class Beer { String name String style Recipe recipe
创建配方
,并在表单中检索它作为隐藏字段,以便使用
与配方表单一起提交(我知道未设置隐藏属性)。我做错了什么?还有没有更好的方法来创建此关联
啤酒领域类
class Beer {
String name
String style
Recipe recipe
String toString() {
name
}
static hasMany = [recipe : Recipe]
static constraints = {
}
}
class Recipe {
String name
Float grainAmount
String yeast
float boilTime
Float hopAmount
float og
float fg
float ogTemp
float fgTemp
float fermTime
Beer beer
static belongsTo = [ beer: Beer]
static constraints = {
beer nullable: true
}
String toString() {
name
}
}
配方域类
class Beer {
String name
String style
Recipe recipe
String toString() {
name
}
static hasMany = [recipe : Recipe]
static constraints = {
}
}
class Recipe {
String name
Float grainAmount
String yeast
float boilTime
Float hopAmount
float og
float fg
float ogTemp
float fgTemp
float fermTime
Beer beer
static belongsTo = [ beer: Beer]
static constraints = {
beer nullable: true
}
String toString() {
name
}
}
啤酒控制器
package com.example
import static org.springframework.http.HttpStatus.*
import grails.transaction.Transactional
@Transactional(readOnly = true)
class BeerController {
static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]
def index(Integer max) {
params.max = Math.min(max ?: 10, 100)
respond Beer.list(params), model:[beerCount: Beer.count()]
}
def show(Beer beer) {
respond beer
}
def create() {
respond new Beer(params)
}
@Transactional
def save(Beer beer) {
if (beer == null) {
transactionStatus.setRollbackOnly()
notFound()
return
}
if (beer.hasErrors()) {
transactionStatus.setRollbackOnly()
respond beer.errors, view:'create'
return
}
beer.save flush:true
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.created.message', args: [message(code: 'beer.label', default: 'Beer'), beer.id])
redirect beer
}
'*' { respond beer, [status: CREATED] }
}
}
def edit(Beer beer) {
respond beer
}
@Transactional
def update(Beer beer) {
if (beer == null) {
transactionStatus.setRollbackOnly()
notFound()
return
}
if (beer.hasErrors()) {
transactionStatus.setRollbackOnly()
respond beer.errors, view:'edit'
return
}
beer.save flush:true
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.updated.message', args: [message(code: 'beer.label', default: 'Beer'), beer.id])
redirect beer
}
'*'{ respond beer, [status: OK] }
}
}
@Transactional
def delete(Beer beer) {
if (beer == null) {
transactionStatus.setRollbackOnly()
notFound()
return
}
beer.delete flush:true
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.deleted.message', args: [message(code: 'beer.label', default: 'Beer'), beer.id])
redirect action:"index", method:"GET"
}
'*'{ render status: NO_CONTENT }
}
}
protected void notFound() {
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'beer.label', default: 'Beer'), params.id])
redirect action: "index", method: "GET"
}
'*'{ render status: NOT_FOUND }
}
}
}
package com.example
import static org.springframework.http.HttpStatus.*
import grails.transaction.Transactional
@Transactional(readOnly = true)
class RecipeController {
static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]
def index(Integer max) {
params.max = Math.min(max ?: 10, 100)
respond Recipe.list(params), model:[recipeCount: Recipe.count()]
}
def show(Recipe recipe) {
respond recipe
}
def create() {
respond new Recipe(params)
}
@Transactional
def save(Recipe recipe) {
if (recipe == null) {
transactionStatus.setRollbackOnly()
notFound()
return
}
if (recipe.hasErrors()) {
transactionStatus.setRollbackOnly()
respond recipe.errors, view:'create'
return
}
recipe.save flush:true
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.created.message', args: [message(code: 'recipe.label', default: 'Recipe'), recipe.id])
redirect recipe
}
'*' { respond recipe, [status: CREATED] }
}
}
def edit(Recipe recipe) {
respond recipe
}
@Transactional
def update(Recipe recipe) {
if (recipe == null) {
transactionStatus.setRollbackOnly()
notFound()
return
}
if (recipe.hasErrors()) {
transactionStatus.setRollbackOnly()
respond recipe.errors, view:'edit'
return
}
recipe.save flush:true
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.updated.message', args: [message(code: 'recipe.label', default: 'Recipe'), recipe.id])
redirect recipe
}
'*'{ respond recipe, [status: OK] }
}
}
@Transactional
def delete(Recipe recipe) {
if (recipe == null) {
transactionStatus.setRollbackOnly()
notFound()
return
}
recipe.delete flush:true
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.deleted.message', args: [message(code: 'recipe.label', default: 'Recipe'), recipe.id])
redirect action:"index", method:"GET"
}
'*'{ render status: NO_CONTENT }
}
}
protected void notFound() {
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'recipe.label', default: 'Recipe'), params.id])
redirect action: "index", method: "GET"
}
'*'{ render status: NOT_FOUND }
}
}
}
配方控制器
package com.example
import static org.springframework.http.HttpStatus.*
import grails.transaction.Transactional
@Transactional(readOnly = true)
class BeerController {
static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]
def index(Integer max) {
params.max = Math.min(max ?: 10, 100)
respond Beer.list(params), model:[beerCount: Beer.count()]
}
def show(Beer beer) {
respond beer
}
def create() {
respond new Beer(params)
}
@Transactional
def save(Beer beer) {
if (beer == null) {
transactionStatus.setRollbackOnly()
notFound()
return
}
if (beer.hasErrors()) {
transactionStatus.setRollbackOnly()
respond beer.errors, view:'create'
return
}
beer.save flush:true
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.created.message', args: [message(code: 'beer.label', default: 'Beer'), beer.id])
redirect beer
}
'*' { respond beer, [status: CREATED] }
}
}
def edit(Beer beer) {
respond beer
}
@Transactional
def update(Beer beer) {
if (beer == null) {
transactionStatus.setRollbackOnly()
notFound()
return
}
if (beer.hasErrors()) {
transactionStatus.setRollbackOnly()
respond beer.errors, view:'edit'
return
}
beer.save flush:true
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.updated.message', args: [message(code: 'beer.label', default: 'Beer'), beer.id])
redirect beer
}
'*'{ respond beer, [status: OK] }
}
}
@Transactional
def delete(Beer beer) {
if (beer == null) {
transactionStatus.setRollbackOnly()
notFound()
return
}
beer.delete flush:true
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.deleted.message', args: [message(code: 'beer.label', default: 'Beer'), beer.id])
redirect action:"index", method:"GET"
}
'*'{ render status: NO_CONTENT }
}
}
protected void notFound() {
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'beer.label', default: 'Beer'), params.id])
redirect action: "index", method: "GET"
}
'*'{ render status: NOT_FOUND }
}
}
}
package com.example
import static org.springframework.http.HttpStatus.*
import grails.transaction.Transactional
@Transactional(readOnly = true)
class RecipeController {
static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]
def index(Integer max) {
params.max = Math.min(max ?: 10, 100)
respond Recipe.list(params), model:[recipeCount: Recipe.count()]
}
def show(Recipe recipe) {
respond recipe
}
def create() {
respond new Recipe(params)
}
@Transactional
def save(Recipe recipe) {
if (recipe == null) {
transactionStatus.setRollbackOnly()
notFound()
return
}
if (recipe.hasErrors()) {
transactionStatus.setRollbackOnly()
respond recipe.errors, view:'create'
return
}
recipe.save flush:true
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.created.message', args: [message(code: 'recipe.label', default: 'Recipe'), recipe.id])
redirect recipe
}
'*' { respond recipe, [status: CREATED] }
}
}
def edit(Recipe recipe) {
respond recipe
}
@Transactional
def update(Recipe recipe) {
if (recipe == null) {
transactionStatus.setRollbackOnly()
notFound()
return
}
if (recipe.hasErrors()) {
transactionStatus.setRollbackOnly()
respond recipe.errors, view:'edit'
return
}
recipe.save flush:true
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.updated.message', args: [message(code: 'recipe.label', default: 'Recipe'), recipe.id])
redirect recipe
}
'*'{ respond recipe, [status: OK] }
}
}
@Transactional
def delete(Recipe recipe) {
if (recipe == null) {
transactionStatus.setRollbackOnly()
notFound()
return
}
recipe.delete flush:true
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.deleted.message', args: [message(code: 'recipe.label', default: 'Recipe'), recipe.id])
redirect action:"index", method:"GET"
}
'*'{ render status: NO_CONTENT }
}
}
protected void notFound() {
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'recipe.label', default: 'Recipe'), params.id])
redirect action: "index", method: "GET"
}
'*'{ render status: NOT_FOUND }
}
}
}
啤酒/表演普惠制
<!DOCTYPE html>
<html>
<head>
<meta name="layout" content="main" />
<g:set var="entityName" value="${message(code: 'beer.label', default: 'Beer')}" />
<title><g:message code="default.show.label" args="[entityName]" /></title>
</head>
<body>
<a href="#show-beer" class="skip" tabindex="-1"><g:message code="default.link.skip.label" default="Skip to content…"/></a>
<div class="nav" role="navigation">
<ul>
<li><a class="home" href="${createLink(uri: '/')}"><g:message code="default.home.label"/></a></li>
<li><g:link class="list" action="index"><g:message code="default.list.label" args="[entityName]" /></g:link></li>
<li><g:link class="list" action="create" resource="recipe">New Recipe</g:link></li>
</ul>
</div>
<div id="show-beer" class="content scaffold-show" role="main">
<h1><g:message code="default.show.label" args="[entityName]" /></h1>
<g:if test="${flash.message}">
<div class="message" role="status">${flash.message}</div>
</g:if>
<g:link controller="recpie" action="create" resource="recipe" params="[beerid: selectedBeer.id]">Create Recipe</g:link>
<f:display bean="beer" />
<g:form resource="${this.beer}" method="DELETE">
<fieldset class="buttons">
<g:link class="edit" action="edit" resource="${this.beer}"><g:message code="default.button.edit.label" default="Edit" /></g:link>
<input class="delete" type="submit" value="${message(code: 'default.button.delete.label', default: 'Delete')}" onclick="return confirm('${message(code: 'default.button.delete.confirm.message', default: 'Are you sure?')}');" />
</fieldset>
</g:form>
</div>
</body>
</html>
- 新配方
${flash.message}
创建配方
**配方/创建GSP**
<%@ page import="com.example.Beer" %>
<!DOCTYPE html>
<html>
<head>
<meta name="layout" content="main" />
<g:set var="entityName" value="${message(code: 'recipe.label', default: 'Recipe')}" />
<title><g:message code="default.create.label" args="[entityName]" /></title>
</head>
<body>
<a href="#create-recipe" class="skip" tabindex="-1"><g:message code="default.link.skip.label" default="Skip to content…"/></a>
<div class="nav" role="navigation">
<ul>
<li><a class="home" href="${createLink(uri: '/')}"><g:message code="default.home.label"/></a></li>
<li><g:link class="list" action="index"><g:message code="default.list.label" args="[entityName]" /></g:link></li>
</ul>
</div>
<div id="create-recipe" class="content scaffold-create" role="main">
<h1><g:message code="default.create.label" args="[entityName]" /></h1>
<g:if test="${flash.message}">
<div class="message" role="status">${flash.message}</div>
</g:if>
<g:hasErrors bean="${this.recipe}">
<ul class="errors" role="alert">
<g:eachError bean="${this.recipe}" var="error">
<li <g:if test="${error in org.springframework.validation.FieldError}">data-field-id="${error.field}"</g:if>><g:message error="${error}"/></li>
</g:eachError>
</ul>
</g:hasErrors>
<g:form action="save" name="recipeForm">
<fieldset class="form">
Name:
<g:field type="text" name="name"/>
Grain Amount:
<g:field type="text" name="grainAmount"/>
Yeast:
<g:field type="text" name="yeast"/>
Boil Time:
<g:field type="text" name="boilTime"/>
Hop Amount:
<g:field type="text" name="hopAmount"/>
OG:
<g:field type="text" name="og"/>
FG:
<g:field type="text" name="fg"/>
OG Temp:
<g:field type="text" name="ogTemp"/>
FG Temp:
<g:field type="text" name="fgTemp"/>
Ferment Time:
<g:field type="text" name="fermTime"/>
beer:
<g:hiddenField name="beerid" value="${params.beerid}" />
</fieldset>
<fieldset class="buttons">
<g:submitButton name="create" class="save" value="${message(code: 'default.button.create.label', default: 'Create')}" />
</fieldset>
</g:form>
</div>
</body>
</html>
${flash.message}
姓名:
粮食数量:
酵母:
煮沸时间:
跳数:
OG:
前景:
OG温度:
FG温度:
发酵时间:
啤酒:
您已经从名为beerid的啤酒秀页面提交了啤酒ID,因此您需要从配方创建页面上的参数中检索啤酒ID,如下所示:
beer-show.gsp
<g:link controller="recipe" action="create" resource="recipe" params="[beerid: beer.id]">Create Recipe</g:link>
<g:hiddenField name="beer.id" value="${params.beerid}"/>
您已从名为beerid的啤酒秀页面提交了啤酒ID,因此需要从配方创建页面上的参数中检索该啤酒ID,如下所示:
beer-show.gsp
<g:link controller="recipe" action="create" resource="recipe" params="[beerid: beer.id]">Create Recipe</g:link>
<g:hiddenField name="beer.id" value="${params.beerid}"/>
在我的啤酒秀中,我无法解析symbol selectedBeer.id。我想我的控制器中缺少了什么。我在表演中只有啤酒。据我所知,应该将啤酒对象发送到正确的视图?您如何将数据输入啤酒展gsp?在地图上?啤酒域实例的名称是否为selectedBeer?啤酒域对象上的其他字段如何显示?更新了答案,在gspLet us中使用啤酒而不是selectedBeer作为域名。在我的啤酒秀中,我无法解析symbol selectedBeer.id。我想我的控制器中缺少了什么。我在表演中只有啤酒。据我所知,应该将啤酒对象发送到正确的视图?您如何将数据输入啤酒展gsp?在地图上?beer域实例的名称是否selectedBeer?其他字段如何显示在beer域对象上?更新了答案,在gspLet us中使用beer而不是selectedBeer作为域名。