我在 grails 应用程序中使用的插件(Nimble 0.3)包括一些控制器和相关操作。我想(稍微)改变一些动作行为,我想知道如何实现这一点。
我可以创建一个从我的插件控制器继承的子控制器并覆盖一些操作实现吗?
或者,我可以创建另一个与插件控制器同名但位于不同包中的控制器吗?
那么实际上我真正需要了解的是:当存在名称冲突时,Grails 如何确定调用哪个控制器操作?
我在 grails 应用程序中使用的插件(Nimble 0.3)包括一些控制器和相关操作。我想(稍微)改变一些动作行为,我想知道如何实现这一点。
我可以创建一个从我的插件控制器继承的子控制器并覆盖一些操作实现吗?
或者,我可以创建另一个与插件控制器同名但位于不同包中的控制器吗?
那么实际上我真正需要了解的是:当存在名称冲突时,Grails 如何确定调用哪个控制器操作?
假设您有一个名为 PluginController 的插件控制器和一个要覆盖的操作 'foo',您可以对控制器进行子类化:
class MyController extends PluginController {
def foo = {
...
}
}
但是你需要在 UrlMappings 中做一些工作:
class UrlMappings {
static mappings = {
"/$controller/$action?/$id?" {
constraints {}
}
"/myController/foo/$id?"(controller: "myController", action: "foo")
"/myController/$action?/$id?"(controller: "pluginController")
"/pluginController/$action?/$id?"(controller: "errors", action: "urlMapping")
"/"(view:"/index")
"500"(view:'/error')
"404"(controller: "errors", action: "notFound")
}
}
这取决于一个ErrorsController:
class ErrorsController {
def notFound = {
log.debug "could not find $request.forwardURI"
}
def urlMapping = {
log.warn "unexpected call to URL-Mapped $request.forwardURI"
render view: 'notFound'
}
}
如果您调用旧的“未映射”控制器操作,则会呈现 404 页面。您需要创建 grails-app/views/errors/notFound.gsp 以显示适当的 404 页面。
第一个 url 映射确保调用您的覆盖操作。第二个将其他所有内容路由到原始控制器。第三个发送 404 用于直接访问。
使用 Grails 1.3.7 和 Nimble 插件 0.4,我发现 Burt 的 UrlMapping 解决方案对我不起作用。但是,根据 Burt 的其他答案,只需创建一个控制器,它既是插件控制器的子类,又具有相同的名称。
class AuthController extends grails.plugins.nimble.core.AuthController{
private static String TARGET = 'grails.plugins.nimble.controller.AuthController.TARGET'
def login = {
// custom logic here
}
}
我会将原始类子类化并覆盖您需要的行为。我用另一个插件做了很多这样的事情,而且效果很好。
另一种方法当然是使用内联插件并只修改原始源代码,但更糟糕的是,因为升级会有问题。
我也是 Nimble 的用户,如果您认为您的扩展可以被其他人使用,那么您可以做出贡献 - Nimble 肯定会尝试确保它非常可扩展。