Grails:在插件中添加动态方法

时间:2010-01-28 00:02:31

标签: grails metaprogramming grails-plugin

我正在开发一个插件,为每个控制器添加getFlashHelper方法。此方法应返回FlashHelper类的实例。

但是,FlashHelper类的构造函数必须传递调用getFlashHelper方法的控制器的实例

希望以下代码能够解释我的工作做得更好

def doWithDynamicMethods = {ctx ->

    application.controllerClasses*.metaClass*.getFlashHelper = {

        def controllerInstance = delegate

        // Avoid creating a new FlashHelper each time the 'flashHelper' property is accessed
        if (!controllerInstance.metaClass.hasProperty('flashHelperInstance')) {
            controllerInstance.metaClass.flashHelperInstance = new FlashHelper(controller: controllerInstance)
        }

        // Return the FlashHelper instance. There may be a simpler way, but I tried
        // controllerInstance.metaClass.getMetaProperty('flashHelperInstance')
        // and it didn't work
        return controllerInstance.metaClass.getMetaProperty('flashHelperInstance').getter.invoke(controllerInstance, [] as Object[])
    }
}

代码似乎有效,但我不禁觉得必须有一种更简单的方法。最后一行尤其令人毛骨悚然。有什么方法可以简化这个吗?

谢谢, 唐

1 个答案:

答案 0 :(得分:1)

由于控制器是按请求创建的,因此我将帮助器存储为Request属性:

for (c in grailsApplication.controllerClasses) {
   c.clazz.metaClass.getFlashHelper = { ->
      def controllerInstance = delegate
      def request = controllerInstance.request
      def helper = request['__flash_helper__']
      if (!helper) {
         helper = new FlashHelper(controller: controllerInstance)
         request['__flash_helper__'] = helper
      }
      helper
   }
}