Come chiamare un servizio Grails in una vista?
Domanda
Domanda semplice:
Ho una classe di servizio (diciamo helpersService
) e un metodo def constructURI (params)
.
Come posso chiamare questo metodo da una vista modello.
Ho provato il seguente codice senza successo
<% def helpersService = new HelpersService() // or def helpersService
%>
<img src="${helpersService. constructURI(params)}"/>
Ma ottengo il seguente risultato:
No signature of method: com.HelpersService. constructURI() is applicable for argument types...
o (nel caso in cui utilizzo def helpersService
)
Cannot invoke method constructURI() on null object
Qualche idea?
Soluzione
I servizi non devono essere utilizzati all'interno delle viste. È possibile creare un TagLib in cui è possibile ottenere un riferimento al servizio tramite iniezione di dipendenza.
Altri suggerimenti
Un metodo più semplice, supponendo che la visualizzazione venga eseguita da un controller, è semplicemente passare un riferimento al servizio dall'azione alla vista all'interno del modello, ovvero:
class someController {
def someService
def someAction = {
render(view: 'someView', model: ['someService': someService])
}
}
Può quindi essere utilizzato come previsto nella vista. Per un modello reso da una vista, ovviamente è necessario passare anche il riferimento al modello. Per essere chiari, però, S. Puchbauer ha ragione; non si suppone che i servizi vengano effettivamente utilizzati in Views e potresti riscontrare problemi di diagnosi difficili, in particolare relativi alle transazioni e alla sessione di ibernazione.
Ho scoperto che questo codice incorporato in linea funziona:
<% def xxxService = application.getAttribute("org.codehaus.groovy.grails.APPLICATION_CONTEXT").getBean("xxxService") %>
Puoi chiamare le funzioni del servizio in questo modo:
<g:select optionKey="key" from="${xxxService.getWhateverList()}" name="tarif" value="${accountInstance?.tarif}" ></g:select>
Beh, ho trovato una soluzione alternativa con il seguente codice:
def helpersService = grailsApplication.classLoader.loadClass('HelpersService').newInstance()
Comunque è meglio usare il servizio tramite iniezione di dipendenza, quindi proverò i consigli di Siegfried.
Puoi farlo facilmente senza creare un tag lib usando il tag set:
<g:set var="versionService" bean="versionService"/>
...
<p>version ${versionService.clientVersion}</p>
Ho trovato questa soluzione qui: http: //mrhaki.blogspot.com/2013/08/grails-goodness-use-services-in-gsp.html