我在域类中有静态方法返回一个url.我需要动态构建该URL,但g.link无法正常工作.
static Map options() {
// ...
def url = g.link( controller: "Foo", action: "bar" )
// ...
}
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
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
Run Code Online (Sandbox Code Playgroud)
显然我的问题是我试图g从静态上下文访问,所以我该如何解决这个问题呢?
该g对象是一个taglib,它在域类中不可用,就像它在控制器中一样.您可以通过grailsApplication此处显示:如何将Taglib称为域类中的函数
在Grails 2+中更好的方法是通过grailsLinkGenerator服务,如下所示:
def grailsLinkGenerator
def someMethod() {
def url = grailsLinkGenerator.link(controller: 'foo', action: 'bar')
}
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,你需要做一些额外的工作来获取grailsApplication/ grailsLinkGenerator从静态上下文.最好的方法可能是从domainClass域类的属性中获取它:
def grailsApplication = new MyDomain().domainClass.grailsApplication
def grailsLinkGenerator = new MyDomain().domainClass.grailsApplication.mainContext.grailsLinkGenerator
Run Code Online (Sandbox Code Playgroud)
如果您使用的是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')]
}
}
Run Code Online (Sandbox Code Playgroud)
具有静态方法的实用类
@Singleton
class ContextUtil implements ApplicationContextAware {
private ApplicationContext context
void setApplicationContext(ApplicationContext context) {
this.context = context
}
static LinkGenerator getLinkGenerator() {
getInstance().context.getBean("grailsLinkGenerator")
}
}
Run Code Online (Sandbox Code Playgroud)
新工具Bean的Bean Def
beans = {
contextUtil(ContextUtil) { bean ->
bean.factoryMethod = 'getInstance'
}
}
Run Code Online (Sandbox Code Playgroud)
如果您需要基本URL,请添加absolute:true到链接调用.