我正在尝试将我的grails应用程序从版本1.3升级到2.5。我有一个域类,其字段之一为Enum。在 Controller 中,当我执行domainObj.validate()时,它始终返回false。验证错误为-
grails.validation.ValidationErrors:1个错误
字段“typeEnum”上的对象“Parameter”中的字段错误:拒绝的值[0];默认值为0。代码[com.TypeEnum.typeMismatch.error,com.TypeEnum.typeMismatch,com.TypeEnum.typeMismatch.error,com.TypeEnum.typeMismatch,typeMismatch.com.TypeEnum,typeMismatch.pspValueTypeEnum,typeMismatch.com.TypeEnum,typeMismatch]参数[typeEnum];默认消息[没有枚举常量com.TypeEnum.0]
编辑:在进一步分析中,我发现问题不在于枚举,而是当执行parameterObj.properties = params时,parameterObj.validate()返回false。
在我的Grails 2.5代码中,
parameterObj.validate() //returns true
parameterObj.properties = params
// code to convert String from params to Enum object and assign it to parameterObj
parameterObj.enumField = MyEnumClass.getEnumByName(params.enumNameValue)
parameterObj.validate() //This always return false
注意:在以上两种validate()情况下,parameterObj的字段值都完全相同
在Grails 2.5中对域类使用属性时是否有任何更改?
最佳答案
如果更改 View ,以使它们将枚举的name()作为参数值发送,则数据绑定(bind)即开即用。
至少这就是我一直使用枚举的方式。
使用name()进行枚举数据绑定(bind)
<g:select name="typeEnum" from="${TypeEnum.values()}" value="${obj.typeEnum}"/>
然后grails使用每个枚举值的.name()作为值,并使用.toString()作为显示的文本。这将生成如下内容:
<select name="typeEnum">
<option value="STRING">String</option>
<option value="NUMBER">Number</option>
...
</select>
Controller 中的数据绑定(bind)然后可以与域或命令对象一起正常工作:
def save1(PsparameterCmd cmd) {
...
instance.properties = cmd.properties
}
def save2() {
...
instance.properties = params
}
自定义枚举数据绑定(bind)
或者,您可以使用自定义数据绑定(bind)将ID转换为枚举值。
有不同的方法(文档:http://docs.grails.org/2.5.0/guide/theWebLayer.html#dataBinding):
*您可以为该类型注册一个全局数据绑定(bind)器(如果您在应用中经常使用该枚举)
*您可以在该单个字段上指定一个dataBinding注释(用于单次使用)
class Psparameter implements java.io.Serializable {
@BindUsing({ obj, params ->
return TypeEnum.values().find({ it.id == params.int('typeId') })
})
TypeEnum typeEnum
...
}
或全局转换器:
import org.grails.databinding.converters.ValueConverter
class TypeEnumConverter implements ValueConverter {
boolean canConvert(value) {
value instanceof Integer
}
def convert(value) {
return TypeEnum.values().find({ it.id == value })
}
Class<?> getTargetType() {
TypeEnum
}
}
您必须在resources.groovy中注册
beans = {
typeEnumConverter(your.package.TypeEnumConverter)
}
注意:据我所知(并经过测试),没有像TypeEnum.getTypeEnumById(value)这样的通用方法。这就是为什么我在上面的示例中对TypeEnum.values()使用查找的原因。
关于grails - 当domainObj.properties = params时,Grails 2.5:domainObj.validate()方法返回false,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39447552/