Comment appeler un service Grails dans une vue?
Question
Question simple:
J'ai une classe de service (disons helpersService
) et une méthode def constructURI (params)
.
Comment puis-je appeler cette méthode à partir d'une vue de modèle?
J'ai essayé le code suivant sans succès
<% def helpersService = new HelpersService() // or def helpersService
%>
<img src="${helpersService. constructURI(params)}"/>
Mais j'obtiens le résultat suivant:
No signature of method: com.HelpersService. constructURI() is applicable for argument types...
ou (si j'utilise def helpersService
)
Cannot invoke method constructURI() on null object
Des idées?
La solution
Les services ne sont pas destinés à être utilisés dans des vues. Vous pouvez créer une balise TagLib dans laquelle vous pourrez obtenir une référence au service via l’injection de dépendance.
Autres conseils
Une méthode plus simple, en supposant que votre vue soit rendue par un contrôleur, consiste à simplement passer une référence au service de l'action à la vue dans le modèle, c'est-à-dire:
.class someController {
def someService
def someAction = {
render(view: 'someView', model: ['someService': someService])
}
}
Il peut ensuite être utilisé comme vous le souhaitez dans la vue. Pour un modèle rendu par une vue, il est évident que vous devez également transmettre la référence au modèle. Soyons clairs, S. Puchbauer a raison; Les services ne sont pas vraiment censés être utilisés dans Views et vous pouvez rencontrer des difficultés pour diagnostiquer les problèmes, notamment ceux liés aux transactions et à la session Hibernate.
J'ai découvert que ce code en ligne groovy fonctionne:
<% def xxxService = application.getAttribute("org.codehaus.groovy.grails.APPLICATION_CONTEXT").getBean("xxxService") %>
Vous pouvez appeler des fonctions du service comme suit:
<g:select optionKey="key" from="${xxxService.getWhateverList()}" name="tarif" value="${accountInstance?.tarif}" ></g:select>
Eh bien, j'ai trouvé une solution de contournement avec le code suivant:
def helpersService = grailsApplication.classLoader.loadClass('HelpersService').newInstance()
Cependant, il est préférable d’utiliser Service via l’injection de dépendances. Je vais donc essayer les conseils de Siegfried.
Vous pouvez le faire facilement sans créer de balise lib en utilisant la balise set:
<g:set var="versionService" bean="versionService"/>
...
<p>version ${versionService.clientVersion}</p>
J'ai trouvé cette solution ici: http: //mrhaki.blogspot.com/2013/08/grails-goodness-use-services-in-gsp.html