重写基架控制器中的模板方法



我有一个Grails项目,我使用高度定制的脚手架模板将beforeUpdate模板方法添加到update,以便我可以轻松地自定义脚手架Controller,而无需单独生成然后编辑每个控制器。

不幸的是,这不起作用,只能调用脚手架中的beforeUpdate。我怀疑这与Groovy用于将脚手架代码注入实际Controller的代码生成有关,但我找不到任何确认。

我问的是解决问题的方法或解释为什么它不起作用。

这是脚手架代码:

def beforeUpdate = {
    println "beforeUpdate from scaffold"
}
def update() {
    // call before update hook
    beforeUpdate()
    def ${propertyName} = ${className}.get(params.id)
    if (!${propertyName}) {
        flash.message = message(code: 'default.not.found.message', args: [message(code: '${domainClass.propertyName}.label', default: '${className}'), params.id])
        redirect(action: "list")
        return
    }
    [...]

和脚手架控制器代码(没有调用,但我相信它应该):

class CalendarController {
    static scaffold = Calendar
    def beforeUpdate = {
            println "beforeUpdate from controller"
    }
}

我已经尝试过干净的圣杯;-)

更新

我最终意识到,由于圣杯脚手架的设计方式,这根本不可能。关闭。

你对这个问题有一个类似的问题 - 本质上是脚手架的工作方式,脚手架模板会生成一个单独的类,"真正的"控制器委托给该类。 所以如果你想让生成的控制器调用你不能使用this的实体控制器上的方法,你需要获取对真实控制器对象的引用。

长话短说,请使用

GrailsWebUtil.getControllerFromRequest(request).beforeUpdate()

而不仅仅是

beforeUpdate()

def update() {
    // call before update hook
    def realController = GrailsWebUtil.getControllerFromRequest(request)
    if(realController.hasProperty('beforeUpdate') &&
         realController.beforeUpdate instanceof Closure) {
      realController.beforeUpdate()
    } else {
      this.beforeUpdate()
    }
    def ${propertyName} = ${className}.get(params.id)
    if (!${propertyName}) {
        flash.message = message(code: 'default.not.found.message', args: [message(code: '${domainClass.propertyName}.label', default: '${className}'), params.id])
        redirect(action: "list")
        return
    }
    [...]

我最终意识到,由于 Grails 脚手架的设计方式,这根本不可能:通过将方法动态复制/创建到脚手架控制器中,而不是使用继承。

最新更新