在书籍
Getting Started with Grails – 2e,第42页(电子页面,而不是纸质页面)中,列出了以下示例.
class Race { static constraints = { name(blank:false,maxSize:50) // NOTE: This doesn’t do // what you think it does startDate(min: new Date()) // And this is what we're supposed // to be using: // startDate(validator: {return (it > new Date())}) } String name Date startDate // ... }
然后建议读者使用上面注释的startDate版本.引用的原因是:静态约束属性只会被评估一次(在服务器启动时),而我们的目的是在每个实例化和随后的Race验证中对其进行评估.
我的问题是:为什么名称约束的非闭包样式适用于每次验证尝试但不适用于startDate约束?而且,相反,如果startDate需要封闭风格,那么为什么名称也不需要呢?
如果我正确理解上面的Groovy语法,似乎静态约束块中列出的每个约束在语法上都是对函数的调用,该函数将各种验证属性作为Map.现在,由于静态块将在服务器启动时进行评估(一次),因此两个函数调用也会在服务器启动时发生(一次),并且应该在非闭包形式中导致相同且一致的行为.不是吗?
解决方法
如果你选择:
startDate(min: new Date())
然后将在服务器启动时评估新的Date(),并且永远不会更改.所以下周(假设服务器继续运行)它将验证上周的日期.
第二种形式:
startDate(validator: {return (it > new Date())})
将在每次检查约束时进行评估,因此无论服务器运行多长时间,它都将始终针对当前进行验证.
另一方面,当涉及名称时,它针对静态内容进行验证,即maxSize为50,这使得它作为键值对而不是使用验证器闭包是有意义的,因为每次完成验证时都不评估值50为startDate完成的名称.
编辑:
当评估调用名称(maxSize:50)调用时,它实际上为字段名称创建了一个MaxSizeConstraint
object.然后,grails使用此属性 – >约束映射来在验证对象时检查属性.正如您在该课程中所看到的,maxSize是一个私有财产.实际上,如果您希望maxSize随时间变化,那么您需要使用自定义验证器与Date一样