2009-10-22 8 views
6

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.Comment appeler un service Grails dans une vue?

J'ai essayé le code suivant sans succès

<% def helpersService = new HelpersService() // or def helpersService 
%> 
<img src="${helpersService. constructURI(params)}"/> 

Mais j'obtenir le résultat suivant:

No signature of method: com.HelpersService. constructURI() is applicable for argument types... 

ou (au cas où j'utiliser def helpersService)

Cannot invoke method constructURI() on null object 

Toutes les idées ?

+0

répondues ici: http://stackoverflow.com/questions/2510929/how-do-i-call-a-grails-service-from-a-gsp/19378586#19378586 –

Répondre

19

Les services ne sont pas destinés à être utilisés dans des vues. Vous pouvez créer une TagLib où vous pouvez obtenir une référence au service via l'injection de dépendance.

+0

Oui, taglibs sont tellement plus propre tout autour – mbrevoort

+1

voir aussi la question http://stackoverflow.com/questions/2510929/problem-calling-grails-service-from-gsp Exemple taglib: http://stackoverflow.com/a/7005752/160799 (ne semble pas très propre pour moi, cependant. Je préfère la solution http://stackoverflow.com/a/1652410/160799 ci-dessous - encore nouvelle pour Grails mais je n'ai trouvé aucun autre moyen de gérer l'affichage en fonction des droits d'accès pour les éléments dans une liste de résultats de recherche). – Gregor

1

Eh bien j'ai trouvé une solution avec le code suivant:

def helpersService = grailsApplication.classLoader.loadClass('HelpersService').newInstance() 

Cependant, il est préférable d'utiliser le service par injection de dépendance, alors je vais essayer des conseils Siegfried.

7

Une méthode plus simple, en supposant que votre vue doit être rendue par un contrôleur, est de simplement passer une référence au service de l'action à la vue dans le modèle, à savoir:

class someController { 
    def someService 
    def someAction = { 
    render(view: 'someView', model: ['someService': someService]) 
    } 
} 

Il peut alors être utilisé comme vous vous y attendez 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. Pour être clair cependant, S. Puchbauer a raison; les services ne sont pas vraiment supposés être utilisés dans Views, et vous pouvez rencontrer des problèmes difficiles à diagnostiquer, en particulier liés aux transactions et à la session Hibernate.

2

J'ai découvert, que ce groovy code en ligne fonctionne:

<% def xxxService = application.getAttribute("org.codehaus.groovy.grails.APPLICATION_CONTEXT").getBean("xxxService") %> 

Vous pouvez appeler des fonctions de service comme ceci:

<g:select optionKey="key" from="${xxxService.getWhateverList()}" name="tarif" value="${accountInstance?.tarif}" ></g:select> 
+0

Je l'ai utilisé à la rigueur dans une vue d'en-tête universelle, puisque chaque page en aura besoin –

+0

Juste du code, il est assez évident que ce n'est pas un bon modèle à suivre. –

Questions connexes