2012-06-25 9 views
6

Mam metodę statyczną w klasie domeny, która zwraca adres URL. Muszę dynamicznie budować ten URL, ale g.link nie działa.Nie można użyć grails g.link w domenie klasy

static Map options() { 
    // ... 
    def url = g.link(controller: "Foo", action: "bar") 
    // ... 
} 

otrzymuję następujące błędy:

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 

Oczywiście moim problemem jest to, że staram się dostęp g z kontekstu statycznego, więc jak mogę to obejść?

+2

nie rób tego w zakresie statycznego. Użyj metody instancji lub, jeszcze lepiej, umieść ten kod w usłudze, aby mógł zostać wstrzyknięty. – OverZealous

+0

Nie mam instancji w momencie, gdy to robię. – ubiquibacon

+1

Tak, zgadzam się z OverZealous. Naprawdę zły pomysł, aby zrobić to w ten sposób. – Gregg

Odpowiedz

9

Obiekt g to taglib, który nie jest dostępny w klasie domeny, tak jak w kontrolerze. Można uzyskać na nią przez grailsApplication jak pokazano tutaj: How To Call A Taglib As A Function In A Domain Class

Lepszy sposób to zrobić w Grails 2+ jest za pośrednictwem usługi grailsLinkGenerator, tak:

def grailsLinkGenerator 

def someMethod() { 
    def url = grailsLinkGenerator.link(controller: 'foo', action: 'bar') 
} 

W obu przypadkach będziesz trzeba wykonać dodatkową pracę, aby uzyskać grailsApplication/grailsLinkGenerator ze statycznego kontekstu. Najlepszym sposobem jest pewnie chwycić go wyłączyć właściwość domainClass swojej klasie domenie:

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

Byłem tak blisko. Próbowałem linkGenerator, ale otrzymywałem statyczne ostrzeżenia kontekstowe. Usunięcie go z klasy domeny, zgodnie z sugestią, działało dobrze. Dzięki! – ubiquibacon

5

Jeśli korzystasz z Grails 2.x, możesz użyć API LinkGenerator. Oto przykład: ponownie używam klasy domeny, którą testowałem wcześniej, więc zignoruj ​​tę funkcję.

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')] 
    } 
} 

klasy Utility z metodą statyczną

@Singleton 
class ContextUtil implements ApplicationContextAware { 
    private ApplicationContext context 

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

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

} 

Bean Defa dla New Utility Bean

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

Jeśli potrzebujesz podstawowy adres URL, dodać absolute:true do połączenia łącza.

Powiązane problemy