2012-06-25 11 views
6

Ho un metodo statico in una classe di dominio che restituisce un URL. Ho bisogno di costruire quell'url in modo dinamico ma g.link non funziona.Impossibile utilizzare grails g.link nella classe dominio

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

Ottengo i seguenti errori:

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 

Ovviamente il mio problema è che sto cercando di accedere g dal contesto statico, così come faccio a ottenere intorno a questo?

+2

non fare questo in un ambito statico. Utilizzare un metodo di istanza o, ancora meglio, inserire questo codice in un servizio in modo che possa essere iniettato. – OverZealous

+0

Non ho un'istanza al momento sto facendo questo. – ubiquibacon

+1

Sì, sono d'accordo con OverZealous. Davvero cattiva idea di farlo in questo modo. – Gregg

risposta

9

L'oggetto g è un taglib, che non è disponibile all'interno di una classe di dominio come se fosse in un controller. È possibile ottenere a esso attraverso il grailsApplication come illustrato di seguito: How To Call A Taglib As A Function In A Domain Class

Un modo migliore per fare questo in Grails 2+ è attraverso il servizio grailsLinkGenerator, in questo modo:

def grailsLinkGenerator 

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

In entrambi i casi, ti è necessario fare del lavoro extra per ottenere grailsApplication/grailsLinkGenerator da un contesto statico. Il modo migliore è probabilmente quello di afferrarlo fuori la proprietà domainClass della classe di dominio:

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

Ero così vicino. Ho provato linkGenerator, ma stavo ricevendo avvisi di contesto statici. Afferrandolo dalla classe di dominio, come hai suggerito, hai funzionato bene. Grazie! – ubiquibacon

5

Se si utilizza Grails 2.x è possibile utilizzare l'API LinkGenerator. Ecco un esempio, sto riutilizzando una classe di dominio con cui stavo testando prima, quindi ignora le funzionalità relative a non 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')] 
    } 
} 

Utility Class con il metodo statico

@Singleton 
class ContextUtil implements ApplicationContextAware { 
    private ApplicationContext context 

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

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

} 

Bean Def per New Utility Bean

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

Se è necessario l'URL di base, aggiungi absolute:true alla chiamata collegamento.

Problemi correlati