【问题标题】:grails 2.3.x: Strange behavior with autogenerated controllergrails 2.3.x:自动生成控制器的奇怪行为
【发布时间】:2014-09-25 14:34:10
【问题描述】:

一个全新的 grails 2.3.x 项目。我为域类使用自动生成的控制器和视图。我想直接在控制器中设置一个(非空)属性,所以我从 _form.gsp 中删除了输入字段。

领域类:

class Demo {
    String demo
    String status

    static constraints = {
       demo   nullable: false
       status nullable: false

}

在表单中我只填写演示字段。

自动生成的控制器结果:

...
@Transactional
def save(Demo demoInstance) {
    if (demoInstance == null) {
        notFound()
        return
    }

    // set the status property to "test"
    demoInstance.status = "test"

    println "1 STATUS: ${demoInstance.status}"

    if (demoInstance.hasErrors()) {
        println "2 STATUS: ${demoInstance.status}"
        respond demoInstance.errors, view: 'create'
        return
    }
    println "3 STATUS: ${demoInstance.status}"
    ...

填写表格并将状态属性留空导致
println 1 -> 状态 = '测试'
println 2 -> 状态 = '测试'
重定向以创建带有消息的页面:“类 [Demo] 的属性 [status] 不能为空”

当我在 grails 2.2.x 中更改控制器时:

...
@Transactional
def save() {
    def demoInstance = new Demo(params)

    if (demoInstance == null) {
        notFound()
        return
    }

    // set the status property to "test"
    demoInstance.status = "test"

    println "1 STATUS: ${demoInstance.status}"

    if (demoInstance.hasErrors()) {
        println "2 STATUS: ${demoInstance.status}"
        respond demoInstance.errors, view: 'create'
        return
    }
    println "3 STATUS: ${demoInstance.status}"
    ...

这会产生预期的输出:
println 1 -> 状态 = '测试'
println 3 -> 状态 = '测试'
输入存储在数据库中。

谁能解释这种行为?谢谢。

【问题讨论】:

    标签: grails grails-2.3


    【解决方案1】:

    我有同样的问题。不知道确切的原因,但有效的是:
    bindData(demoInstance, [status: 'test'])
    Grails 2.3 有一个新的DataBinding。如果你设置了,你可以使用旧的 Spring 样式
    grails.databinding.useSpringBinder = true 在 Config.groovy
    使用这个SpringBinder,不会出现这个问题。

    【讨论】:

    • Thx pereiss, "grails.databinding.useSpringBinder = true" 解决了我的问题。
    【解决方案2】:

    我不知道您为什么会看到您在 2.2.x 代码中看到的行为,但无论您使用哪种数据绑定器,2.3.x 的行为对我来说都是正确的。数据绑定发生在调用控制器操作之前,并且由于您未设置属性,因此实例存在验证错误。然后设置一个有效值但不调用validate()save(),因此没有理由期望hasErrors() 会从false 变为true。

    如果你添加

    demoInstance.validate()
    

    之后

    demoInstance.status = "test"
    

    那么我希望看到您在 2.2.x 版本中看到的输出(尽管再次,如果没有 validatesave 调用,我无法想象为什么它也会在 2.2 中工作)。

    【讨论】:

    • 您好,感谢您的澄清。那么 hasErrors() 是一个 getter 方法并且不验证域对象? grails将属性绑定到对象后会自动进行验证吗?
    • 是的 - hasErrors() 会产生执行验证的副作用; getter 不应该进行更改。唯一验证的方法是validate
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-23
    • 1970-01-01
    • 2014-07-06
    • 1970-01-01
    • 2014-12-14
    • 2020-03-31
    • 2015-11-07
    相关资源
    最近更新 更多