为啥我不能在自定义字段验证器中返回全局消息键?

Posted

技术标签:

【中文标题】为啥我不能在自定义字段验证器中返回全局消息键?【英文标题】:Why can't I return global message keys within custom field validators?为什么我不能在自定义字段验证器中返回全局消息键? 【发布时间】:2014-06-02 11:53:43 【问题描述】:

我想向字段添加自定义验证器,以强制执行有条件的非空约束。由于此要求在多个对象之间共享,因此我想重用现有的全局(意味着不是对象或字段特定的)消息键。在下面的示例中,我想使用 default.null.message 而不是 objectA.fieldC.null.message

documentation for the Grails validator 似乎是说,可以通过返回表示来自 message.properties 的键的字符串值来表示错误情况。文档表明(强调我的):

闭包可以返回:

null 或 true(或无返回值)表示该值有效 false 表示无效值并使用默认消息代码 一个字符串,用于指示要附加到“classname.propertyName”的错误代码。用于解决错误消息的字符串。 如果无法解析特定字段的消息,则错误代码本身将被解析,从而允许全局错误消息。 一个包含上述字符串的列表,然后是后面的任意数量的参数,这些参数在 grails-app/i18n/message.properties 文件中用作格式化的消息参数。参数的映射如下:参数0到2自动映射为0:属性名,1:类名,2:属性值。其他参数从参数 3 开始映射。

我还发现 Grails bug 在 1.0 中关闭,它似乎几乎完全符合我的要求。

这是我正在做的一个例子。正如你所看到的,我有一种方法可以工作,但让我很烦恼的是,看似更干净的前两个选项不起作用。

class ObjectA 
    ObjectB fieldB
    ObjectC fieldC
    static constraints = 
        fieldC(nullable: true, validator:  value, object, errors ->
            if (object.fieldB != ObjectB.SOMETHING && !value) 
                // Doesn't work
                //return "default.null.message"
                
                // Doesn't work
                //return ["default.null.message"]

                // This works
                errors.rejectValue("defaultBrand", "default.null.message", ["defaultBrand"] as Object[], "The field \"0\" cannot be null")
            
        )
    

这是我message.properties中的条目:

default.null.message=The field "0" cannot be null

我在这里看到了一个 couple questions 与带有自定义错误消息的 Grails 自定义字段验证器相关,但似乎没有任何东西可以解决我的具体情况。

【问题讨论】:

从重复的问题***.com/a/19299423/2051952回答这个问题 虽然这两个问题的答案基本相同,但我认为不应将其标记为重复。由于您提到的问题专门调用了命令对象,我怀疑大多数人在寻找域验证问题的答案时不一定会考虑从列表中选择它。 域类和命令对象的约束相同。 【参考方案1】:

当使用 validate 闭包的三参数(值、对象、错误)版本时,底层代码假定所有错误都将添加到错误对象中。为了返回代表消息键的字符串或字符串列表。

如果也使用Command Objects,行为也是一样的。

这是一个双参数验证闭包的工作示例:

class ObjectA 
    ObjectB fieldB
    ObjectC fieldC
    static constraints = 
        fieldC(nullable: true, validator:  value, object->
            if (object.fieldB != ObjectB.SOMETHING && !value) 
                return "default.null.message"
                // You can also use the list style return (especially if you need to pass additional parameters used by the message)
                //return ["default.null.message"]
            
        )
    

这是一个三参数验证闭包的工作示例:

class ObjectA 
    ObjectB fieldB
    ObjectC fieldC
    static constraints = 
        fieldC(nullable: true, validator:  value, object, errors ->
            if (object.fieldB != ObjectB.SOMETHING && !value) 
                // When "errors" is passed into the closure, you must use it to signal error cases
                errors.rejectValue("defaultBrand", "default.null.message", ["defaultBrand"] as Object[], "The field \"0\" cannot be null")
            
        )
    

【讨论】:

以上是关于为啥我不能在自定义字段验证器中返回全局消息键?的主要内容,如果未能解决你的问题,请参考以下文章

如何在自定义验证器中获取另一个组件的值? [复制]

如何在自定义验证器中获取另一个组件的值? [复制]

为啥使用自定义全局验证器在角度材料 6 的 mat-form 字段中未显示 mat-error

iOS:为啥在自定义 TableViewCell 中写入此文本字段的文本似乎不可读

为啥在自定义身份验证和登录模块中使用克隆?

在自定义分类模板中获取自定义字段