我最近开始了一个新的Grails项目,我正在尝试尽可能多地使用脚手架功能。我使用grails install-templates安装模板并对其进行修改,以便在某些方法可用时依赖当前控制器(例如,show方法将调用renderShow方法(如果可用))。
我遇到的问题是,当从脚手架模板调用该方法时,找不到它,因此抛出异常。如果从实际控制器调用相同的方法,它将按预期工作。
我缺少什么?
为了说明问题,我创建了一个小项目。有趣的提交就是这个: https://github.com/deigote/GrailsScaffoldingMethodCallProblem/commit/0fce966bad6e8004a7133511149c09de54be24bf
运行应用程序时,如果你去testDemoMethod(... / GrailsScaffoldingMethodCallProblem / demo / testDemoMethod),你会“嗨,我是一个方法”,并打印出以下内容:
[public java.lang.Object grailsscaffoldingmethodcallproblem.DemoController.this$2$demoMethod()]
但是如果你去索引(... / GrailsScaffoldingMethodCallProblem / demo / testDemoMethod),会打印一个空列表并获得一个例外:
Message: No signature of method: grailsscaffoldingmethodcallproblem.DemoController.demoMethod() is applicable for argument types: () values: []
Line | Method
->> 11 | index in grailsscaffoldingmethodcallproblem.DemoController
任何线索为什么会发生这种情况或如何绕过它?
修改: Ian Robert的回答解决了这个问题:Controller method not found if called from scaffolding template
答案 0 :(得分:2)
因为脚手架模板中的this
没有引用声明static scaffold = true
的控制器类。当您在控制器类 A 中使用运行时动态脚手架时,脚手架模板用于生成一个单独的类(称之为 B ,但实际上它可能具有相同的名称作为 A 但通过不同的类加载器加载)并且 A 的每个实例将委托给 B 的任何 B的任何动作定义但 A 未明确覆盖。
如果你需要从脚手架代码中获取真实的控制器实例,你可能不得不使用像
这样的技巧import grails.util.GrailsWebUtil
...
def index() {
def realController = GrailsWebUtil.getControllerFromRequest(request)
println realController.respondsTo('demoMethod')
realController.demoMethod()
redirect(action: "list", params: params)
}