【问题标题】:Cannot use grails g.link in domain class无法在域类中使用 grails g.link
【发布时间】:2012-06-26 23:51:10
【问题描述】:

我在返回 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,那么我该如何解决这个问题?

【问题讨论】:

  • 不要在静态范围内执行此操作。使用实例方法,或者更好的是,将此代码放在服务中以便可以注入。
  • 我在执行此操作时没有实例。
  • 是的,我同意 OverZealous 的观点。这样做真的很糟糕。
  • @typoknig:那你做错了,非常错了。控制器不应该用于通用代码。
  • 我这样做的原因是因为我正在构建一个 flexigrid。 flexigrid 将包含许多特定类型的对象,因此对我来说,该方法是静态的是有意义的。 url 是 flexigrid 所需选项的一部分。

标签: grails


【解决方案1】:

g 对象是一个标记库,它在域类中不可用,就像在控制器中一样。您可以通过grailsApplication 获取它,如下所示:How To Call A Taglib As A Function In A Domain Class

在 Grails 2+ 中执行此操作的更好方法是通过 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

【讨论】:

  • 我是如此接近。我确实尝试了 linkGenerator,但我收到了静态上下文警告。按照您的建议从域类中获取它效果很好。谢谢!
【解决方案2】:

如果您使用的是 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 添加到链接调用中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-15
    • 1970-01-01
    • 1970-01-01
    • 2011-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多