使用多选枚举字段为域对象创建表单失败 'Property xxx is type-mismatched'
Create form for domain object with multiselect Enum field fails with 'Property xxx is type-mismatched'
我正在使用带有 GORM 7.0 的 Grails 4.0.4。7.RELEASE
我使用的数据库是 MongoDB
我可以成功 运行 应用程序并导航到域 class 的创建表单。我可以 select 单例字段的值 someOtherEnum
。我可以为 categories
字段设置多个 select 值。但是,当我提交表单时,我收到此消息:'Property categories is type-mismatched'。我根据此处发布的另一个问题的答案使用了这种方法,但它对我不起作用。我没有像那个用户那样使用嵌入式枚举或 hasMany
集合。
控制器和服务由 generate-all
命令生成。
我在 src/main/groovy/com/project/core/dsl
中有一个枚举我正在使用它来填充域的多 select 字段 class:
package com.project.core.dsl
import groovy.transform.CompileStatic
@CompileStatic
enum Category {
CATEGORY_ONE("Category One"),
CATEGORY_TWO("Category Two"),
CATEGORY_THREE("Category Three")
private final String id
private Category(String id) { this.id = id }
@Override
String toString() { id }
String getKey() { name() }
}
域名class:
package com.project.core
import com.project.core.dsl.SomeOtherEnum
import com.project.core.dsl.Category
class DomainObject {
SomeOtherEnum someOtherEnum
Set<Category> categories
static constraints = {
}
static mapping = {
someOtherEnum index: true
}
@Override
String toString() {
return "DomainObject{" +
"someOtherEnum=" + someOtherEnum +
", categories=" + categories +
'}';
}
}
在 create.gsp
视图中,我有这样的表格:
<g:form resource="${this.domainObject}" method="POST">
<fieldset class="form">
<f:with bean="domainObject">
<f:field property="someOtherEnum"/>
<f:field property="categories">
<g:select
multiple="true"
name="${property}"
from="${Category}"
value="${domainObject?.categories}"
/>
</f:field>
</f:with>
</fieldset>
<fieldset class="buttons">
<g:submitButton name="create" class="save" value="${message(code: 'default.button.create.label', default: 'Create')}" />
</fieldset>
</g:form>
域class控制器:
package com.project.core
import grails.validation.ValidationException
import static org.springframework.http.HttpStatus.*
class DomainObject {
DomainObjectService domainObjectService
static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]
def index(Integer max) {
params.max = Math.min(max ?: 10, 100)
respond domainObjectService.list(params), model:[domainObjectCount: domainObjectService.count()]
}
def show(Long id) {
respond domainObjectService.get(id)
}
def create() {
respond new DomainObject(params)
}
def save(DomainObject domainObject) {
if (domainObject == null) {
notFound()
return
}
try {
domainObjectService.save(domainObject)
} catch (ValidationException e) {
respond domainObject.errors, view:'create'
return
}
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.created.message', args: [message(code: 'domainObject.label', default: 'DomainObject'), domainObject.id])
redirect domainObject
}
'*' { respond domainObject, [status: CREATED] }
}
}
def edit(Long id) {
respond domainObjectService.get(id)
}
def update(DomainObject domainObject) {
if (domainObject == null) {
notFound()
return
}
try {
domainObjectService.save(domainObject)
} catch (ValidationException e) {
respond domainObject.errors, view:'edit'
return
}
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.updated.message', args: [message(code: 'domainObject.label', default: 'DomainObject'), domainObject.id])
redirect domainObject
}
'*'{ respond domainObject, [status: OK] }
}
}
def delete(Long id) {
if (id == null) {
notFound()
return
}
domainObjectService.delete(id)
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.deleted.message', args: [message(code: 'domainObject.label', default: 'DomainObject'), 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: 'domainObject.label', default: 'DomainObject'), params.id])
redirect action: "index", method: "GET"
}
'*'{ render status: NOT_FOUND }
}
}
}
域对象服务:
package com.project.core
import grails.gorm.services.Service
@Service(DomainObject)
interface DomainObjectService {
DomainObject get(Serializable id)
List<DomainObject> list(Map args)
Long count()
void delete(Serializable id)
DomainObject save(DomainObject domainObject)
}
通过进行以下更改,我能够克服我的错误。我在 DomainObject
中添加了 hasMany 语句
static hasMany = [categories: Category]
并且我在 create.gsp
文件中进行了这些更改:
<f:field property="categories">
<g:select
multiple="true"
name="${property}"
from="${Category?.values()}"
optionKey="key"
value="${domainObject?.categories}"
/>
</f:field>
我正在使用带有 GORM 7.0 的 Grails 4.0.4。7.RELEASE 我使用的数据库是 MongoDB
我可以成功 运行 应用程序并导航到域 class 的创建表单。我可以 select 单例字段的值 someOtherEnum
。我可以为 categories
字段设置多个 select 值。但是,当我提交表单时,我收到此消息:'Property categories is type-mismatched'。我根据此处发布的另一个问题的答案使用了这种方法,但它对我不起作用。我没有像那个用户那样使用嵌入式枚举或 hasMany
集合。
控制器和服务由 generate-all
命令生成。
我在 src/main/groovy/com/project/core/dsl
中有一个枚举我正在使用它来填充域的多 select 字段 class:
package com.project.core.dsl
import groovy.transform.CompileStatic
@CompileStatic
enum Category {
CATEGORY_ONE("Category One"),
CATEGORY_TWO("Category Two"),
CATEGORY_THREE("Category Three")
private final String id
private Category(String id) { this.id = id }
@Override
String toString() { id }
String getKey() { name() }
}
域名class:
package com.project.core
import com.project.core.dsl.SomeOtherEnum
import com.project.core.dsl.Category
class DomainObject {
SomeOtherEnum someOtherEnum
Set<Category> categories
static constraints = {
}
static mapping = {
someOtherEnum index: true
}
@Override
String toString() {
return "DomainObject{" +
"someOtherEnum=" + someOtherEnum +
", categories=" + categories +
'}';
}
}
在 create.gsp
视图中,我有这样的表格:
<g:form resource="${this.domainObject}" method="POST">
<fieldset class="form">
<f:with bean="domainObject">
<f:field property="someOtherEnum"/>
<f:field property="categories">
<g:select
multiple="true"
name="${property}"
from="${Category}"
value="${domainObject?.categories}"
/>
</f:field>
</f:with>
</fieldset>
<fieldset class="buttons">
<g:submitButton name="create" class="save" value="${message(code: 'default.button.create.label', default: 'Create')}" />
</fieldset>
</g:form>
域class控制器:
package com.project.core
import grails.validation.ValidationException
import static org.springframework.http.HttpStatus.*
class DomainObject {
DomainObjectService domainObjectService
static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]
def index(Integer max) {
params.max = Math.min(max ?: 10, 100)
respond domainObjectService.list(params), model:[domainObjectCount: domainObjectService.count()]
}
def show(Long id) {
respond domainObjectService.get(id)
}
def create() {
respond new DomainObject(params)
}
def save(DomainObject domainObject) {
if (domainObject == null) {
notFound()
return
}
try {
domainObjectService.save(domainObject)
} catch (ValidationException e) {
respond domainObject.errors, view:'create'
return
}
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.created.message', args: [message(code: 'domainObject.label', default: 'DomainObject'), domainObject.id])
redirect domainObject
}
'*' { respond domainObject, [status: CREATED] }
}
}
def edit(Long id) {
respond domainObjectService.get(id)
}
def update(DomainObject domainObject) {
if (domainObject == null) {
notFound()
return
}
try {
domainObjectService.save(domainObject)
} catch (ValidationException e) {
respond domainObject.errors, view:'edit'
return
}
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.updated.message', args: [message(code: 'domainObject.label', default: 'DomainObject'), domainObject.id])
redirect domainObject
}
'*'{ respond domainObject, [status: OK] }
}
}
def delete(Long id) {
if (id == null) {
notFound()
return
}
domainObjectService.delete(id)
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.deleted.message', args: [message(code: 'domainObject.label', default: 'DomainObject'), 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: 'domainObject.label', default: 'DomainObject'), params.id])
redirect action: "index", method: "GET"
}
'*'{ render status: NOT_FOUND }
}
}
}
域对象服务:
package com.project.core
import grails.gorm.services.Service
@Service(DomainObject)
interface DomainObjectService {
DomainObject get(Serializable id)
List<DomainObject> list(Map args)
Long count()
void delete(Serializable id)
DomainObject save(DomainObject domainObject)
}
通过进行以下更改,我能够克服我的错误。我在 DomainObject
static hasMany = [categories: Category]
并且我在 create.gsp
文件中进行了这些更改:
<f:field property="categories">
<g:select
multiple="true"
name="${property}"
from="${Category?.values()}"
optionKey="key"
value="${domainObject?.categories}"
/>
</f:field>