我正在尝试将我的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/

10-11 02:55