如何扩展/覆盖插件的控制器动作?

时间:2010-01-31 23:10:41

标签: model-view-controller inheritance grails grails-plugin grails-controller

我在grails应用程序中使用的插件(Nimble 0.3),包括一些控制器和相关的操作。 我想(略微)改变某些行为行为,我想知道如何实现这一目标。

我可以创建一个从我的插件控制器继承的子控制器并覆盖某些操作实现吗?

或者,我可以创建另一个与插件控制器名称相同的 但位于不同的包中吗?

实际上我真正需要理解的是:当名称冲突时,Grails如何确定要调用的控制器操作

3 个答案:

答案 0 :(得分:8)

假设你有一个名为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映射确保调用重写的操作。第二个将其他所有内容路由到原始控制器。第3个发送404s直接访问。

答案 1 :(得分:2)

使用Grails 1.3.7和Nimble插件0.4我发现Burt的UrlMapping解决方案对我不起作用。但是,根据Burt的other answer

,只需创建一个控制器,该控制器同时对插件控制器进行子类化并具有相同的名称。
class AuthController extends grails.plugins.nimble.core.AuthController{

    private static String TARGET = 'grails.plugins.nimble.controller.AuthController.TARGET'

    def login = {
        // custom logic here    
    }
}

答案 2 :(得分:0)

我会将原始类子类化并覆盖您需要的行为。我正在使用另一个插件做很多事情,而且效果很好。

另一种方法当然是使用内联插件并只修改原始来源,但更糟糕的是,因为升级时会出现问题。

我也是Nimble的用户,如果你认为你的扩展可以被其他人使用,那么你可以做出贡献 - 敏捷当然试图确保它是非常可扩展的。