如何在域类中将 Taglib 作为函数调用

Posted

技术标签:

【中文标题】如何在域类中将 Taglib 作为函数调用【英文标题】:How To Call A Taglib As A Function In A Domain Class 【发布时间】:2011-01-10 16:37:45 【问题描述】:

我需要从我的域类中调用静态资源插件 (http://www.grails.org/Static+Resources+Plugin)。

这在控制器中完美运行:

 def tstLink = resourceLinkTo(dir:"docs/$identifier",file:originalFileName)

但是在域类中我得到了

Exception Message: No signature of method: static org.maflt.ibidem.Item.resourceLinkTo() is applicable for argument types: (java.util.LinkedHashMap) values: [[dir:docs/19e9ea9d-5fae-4a35-80a2-daedfbc7c2c2, file:2009-11-12_1552.png]] 

我认为这是一个普遍的问题。

那么如何在域类中将 taglib 作为函数调用呢?

【问题讨论】:

我刚刚遇到了同样的问题,正要自己问这个问题,然后再找到你的问题。 接受的答案适用于一般的 taglib 调用,但对于生成链接的特定用例,您可以通过服务类中的 def grailsLinkGenerator 获得服务中的 grailsLinkGenerator bean .然后您可以调用link 方法并为其传递参数,或者访问serverBaseURL 属性。 @TedNaleid 在我写答案时该选项可能不可用。那将是更清洁的方法。 【参考方案1】:

不久前我在开发一个应用程序时遇到了这个问题。我最终做的是在服务方法中调用标签:

class MyService 
   def grailsApplication //autowired by spring

   def methodThatUsesATag(identifier, originalFileName) 
      //This is the default grails tag library
      def g = grailsApplication.mainContext.getBean('org.codehaus.groovy.grails.plugins.web.taglib.ApplicationTagLib')

      g.resourceLinkTo(dir:"docs/$identifier",file:originalFileName)
   

然后在我的域类中,我也可以通过 spring 自动装配来访问该服务:

class MyDomain 
    String originalFileName
    def myService  //autowired

    static transients = ['myService'] //Necessary so that GORM doesn't try to persist the service instance.

    //You can create a method at this point that uses your
    //service to return what you need from the domain instance.
    def myMethod() 
       myService.methodThatUsesATag(id, originalFileName)
    

【讨论】:

您可以直接在域对象中使用相同的依赖注入 - 您无需使用服务来为您完成工作。 现在可能是这样。我最初不是在回答这个问题的时候。 我还发现,您可以从域对象(或 domainClass.grailsAppliction)调用 getDomainClass().getGrailsApplication() 来获取 GrailsApplication。看起来这在 Grails 2.0 中可用【参考方案2】:

大多数标签库依赖于来自控制器的数据,因此通常无法重用它们,而其他标签库则关注视图逻辑,因此您通常不想将其放入域类中。

也就是说,我相信你有你的理由,所以也许 taglib 的来源会有所帮助:

class ResourceTagLib  

    def externalResourceServerService

    def resourceLinkTo =  attrs ->
        out << externalResourceServerService.uri
        out << '/'
        if(attrs['dir']) 
            out << "$attrs['dir']/"
        
        if(attrs['file']) 
            out << "$attrs['file']"
        
    

即将 externalResourceServerService 注入您的域类,其余的应该很简单。

【讨论】:

谢谢。我本来希望这也能奏效。我做了 def tstLink = externalResourceServerService.resourceLinkTo(dir:"docs/$identifier",file:originalFileName) 但没有方法签名:ExternalResourceServerService.resourceLinkTo() 适用于参数类型:(java.util.LinkedHashMap) 值:[[目录:docs/279a5b71-b05f-4d62-be7b-72a805b005e0,文件:me.jpeg]] 看来我只需要正确获取数据类型。无论是否使用 toString(),这都不起作用 def tstLink2 = externalResourceServerService.resourceLinkTo ("docs/$identifier".toString(),originalFileName)。

以上是关于如何在域类中将 Taglib 作为函数调用的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C++ 中将运算符作为函数调用

Python中将函数作为另一个函数的参数传入并调用

在域类中使用 grails 服务

在没有“调用”函数的 Lua 4 中将表值作为函数参数传递

JavaScript,在公共方法中将私有函数作为字符串调用,而不使用 eval(显示模式)

js中将字符串作为函数名来调用的方法