无法在域类中使用grails g.link

无法在域类中使用grails g.link,grails,Grails,我在域类中有一个返回url的静态方法。我需要动态构建该url,但g.link不起作用 static Map options() { // ... def url = g.link( controller: "Foo", action: "bar" ) // ... } 我得到以下错误: Apparent variable 'g' was found in a static scope but doesn't refer to a local variable, stat

我在域类中有一个返回url的静态方法。我需要动态构建该url,但g.link不起作用

static Map options() {
    // ...
    def url = g.link( controller: "Foo", action: "bar" )
    // ...
}
我得到以下错误:

Apparent variable 'g' was found in a static scope but doesn't refer to a local variable, static field or class. Possible causes:
You attempted to reference a variable in the binding or an instance variable from a static context.
You misspelled a classname or statically imported field. Please check the spelling.
You attempted to use a method 'g' but left out brackets in a place not allowed by the grammar.
 @ line 17, column 19.
           def url = g.link( controller: "Foo", action: "bar" )
                     ^

1 error

显然,我的问题是我试图从静态上下文访问
g
,那么我该如何解决这个问题呢?

如果您使用的是Grails 2.x,那么就可以使用LinkGenerator API。这里有一个例子,我正在重新使用我之前测试过的一个域类,所以忽略与url无关的功能

class Parent {
    String pName

    static hasMany = [children:Child]

    static constraints = {
    }
    static transients = ['grailsLinkGenerator']

    static Map options() {
        def linkGen = ContextUtil.getLinkGenerator();
        return ['url':linkGen.link(controller: 'test', action: 'index')]
    }
}
带有静态方法的实用程序类

@Singleton
class ContextUtil implements ApplicationContextAware {
    private ApplicationContext context

    void setApplicationContext(ApplicationContext context) {
        this.context = context
    }

    static LinkGenerator getLinkGenerator() {
        getInstance().context.getBean("grailsLinkGenerator")
    }

}
新实用程序Bean的Bean Def

beans = {
    contextUtil(ContextUtil) { bean ->
        bean.factoryMethod = 'getInstance'
    }
}

如果需要基本URL,请将
absolute:true
添加到链接调用。

g对象是一个标记库,它在域类中不像在控制器中那样可用。您可以通过
grailsApplication
获得它,如下所示:

在Grails2+中实现这一点的更好方法是通过
grailsLinkGenerator
服务,如下所示:

def grailsLinkGenerator

def someMethod() {
    def url = grailsLinkGenerator.link(controller: 'foo', action: 'bar')
}
在这两种情况下,您都需要做一些额外的工作来从静态上下文中获取
grailsApplication
/
grailsLinkGenerator
。最好的方法可能是从域类的
domainClass
属性中获取它:

def grailsApplication = new MyDomain().domainClass.grailsApplication
def grailsLinkGenerator = new MyDomain().domainClass.grailsApplication.mainContext.grailsLinkGenerator

不要在静态范围内执行此操作。使用实例方法,或者更好的方法,将此代码放入服务中,以便注入。我在这样做时没有实例。是的,我同意过度热心。这样做真是个坏主意。@typoknig:那么你做的事情非常非常错误。控制器不应用于通用代码。我这样做的原因是因为我正在构建FlexGrid。FlexGrid将包含许多特定类型的对象,因此对我来说,该方法是静态的是有意义的。url是flexigrid所需选项的一部分。我非常接近。我确实尝试了linkGenerator,但收到了静态上下文警告。按照您的建议从域类中抓取它效果很好。谢谢