6
votes

Inclure les paramètres booléens avec g: include sont passés sous forme de chaînes à la vue incluse

Je ne sais pas si la modification suivante pose problème ou est intentionnelle.

  class is: ${params.progress.getClass()}
  <g:if test="${params.progress}">
   this should not be displayed
 </g:if>

Ensuite, l'expression de line.gsp prend toujours la valeur true, car le type du paramètre 'progress' est String, pas Boolean.

<g:include view="line.gsp" params="['label':'test', 'progress':false]"/>

Notez que la même chose est applicable pour d'autres types, pas seulement pour les booléens. J'utilise Grails 3.3.8 Cela ne s'est pas produit dans Grails 2.5.2.

Je n'ai rien trouvé à ce sujet en ligne, c'est pourquoi je pose la question ici. Merci.

Modifier:

Comme suggéré par Daniel, j'ai également essayé avec grails 3.3.2. Je viens de créer une application avec grails create-app et de modifier l'index.gsp existant pour inclure line.gsp, comme indiqué dans le code ci-dessus.

Voici une capture d'écran: entrez la description de l'image ici


8 commentaires

Cela fonctionne comme prévu dans Grails 3.3.2 au moins. Je viens de tester votre exemple exact et $ {params.progress.getClass ()} était booléen, et il a été évalué correctement dans un bloc if. Peut-être qu'il se passe autre chose? Y a-t-il une chance que vous passiez déjà un paramètre progress dans la vue parent?


Hmm, j'ai essayé avec 3.3.8, 3.0.0 et grails 2.5.2. J'ai créé les applications à partir de zéro avec Grails create-app. Je viens de créer un simple fichier line.gsp contenant le code de la question, puis j'ai modifié le fichier index.gsp existant pour inclure le fichier line.gsp. Je n'ai fait aucun autre changement. Bizarre.


Que se passe-t-il si vous affichez $ {params.progress} dans votre line.gsp? Ou $ {params.progress.getClass ()} ?


cela est vrai pour les grails 2 et 3, mais il montre java.lang.String () pour les grails 3 tandis que pour les grails 2, c'est java.lang.Boolean. C'est ainsi que j'ai remarqué que la progression était interprétée comme une chaîne, car au départ, j'avais une erreur différente dans le gsp qui était en fait causée par cela. Je vais aussi l'essayer avec Grails 3.3.2. Merci.


@Daniel J'ai aussi essayé avec grails 3.3.2, même sur un système différent, et j'obtiens les mêmes résultats. J'ai édité ma question avec une capture d'écran.


Cela vaut la peine de regarder le code dans org.grails.plugins.web.taglib.UrlMappingTagLib pour la fermeture d'inclusion, cela peut être évident, ou non


Ouais, je l'ai fait. J'ai fini par utiliser


Notez que vous pouvez également g: inclure une vue avec un modèle .


3 Réponses :


0
votes

Oui, c'est vrai. Lorsque vous appelez params.quelque chose , vous accédez en fait à GrailsParameterMap qui est une carte. Donc, votre condition s'évalue en fait comme Map-> get () qui sera Object-> toString () et bien sûr c'est vrai car elle n'est ni nulle ni vide. La solution sera donc la suivante:

<g:if test="${params.getBoolean("progress")}">
   this should not be displayed
</g:if>


3 commentaires

Ouais, j'ai remarqué ça. Ma seule préoccupation était de savoir comment cela a été changé dans Grails 3.


Pourquoi pensez-vous que GrailsParameterMap renvoie nécessairement une valeur String?


Je mentionne dans cette condition uniquement. Vous pouvez vérifier par: $ {params.progress? .GetClass ()} qui affichera: class java.lang.String. Oui: le GrailsParameterMap peut stocker le type diff de Object en valeur sur d'autres scénarios comme toujours.



0
votes

Vous pouvez tester ceci comme suit

<g:if test="${params.progress && params.progress == 'false'}">
   this should not be displayed
 </g:if>


1 commentaires

Ouais, j'ai remarqué ça. Ma seule préoccupation était de savoir comment cela a été changé dans Grails 3. La migration d'une application de Grails 2 vers Grails 3 implique de changer toutes ces occurrences qui fonctionnaient auparavant dans Grails 2.



0
votes

Je sais que vous avez déjà trouvé une solution de contournement à ce problème, mais cela me dérangeait que votre code ne fonctionne pas de la même manière que le mien, alors j'ai décidé d'enquêter un peu plus au cas où quelqu'un d'autre rencontrerait ce problème.

Comme d'autres personnes l'ont mentionné ici, params.anything renverra généralement une valeur String. Cela est dû au fait que les paramètres sont généralement codés en tant que paramètres URI (comme? Progress = false) et ne sont pas automatiquement transférés dans un autre type. (C'est parfaitement raisonnable; il n'y aurait pas de bon moyen pour Grails de savoir de quel type ils devraient être.) Cependant, il est possible (et parfois raisonnable) de rendre votre vue ou votre modèle à partir d'un contrôleur comme render view: peu importe , model: [your: model, params: params] où vous incluez spécifiquement des paramètres dans le modèle. (Peut-être avez-vous beaucoup de paramètres que vous n'avez pas besoin de recréer individuellement dans le modèle.) Dans ce cas, la mappe de paramètres existera à la fois en tant que paramètres d'URI (? Progress = false) et entrée de modèle à portée de page (paramètres: [ progress: Boolean.FALSE]). L'étendue de la page est prioritaire sur les paramètres URI, et donc vos types seront préservés.

Lors de mes tests, j'ai ajouté votre code à une page existante où je passais déjà des paramètres dans le modèle, et donc le type a également été conservé pour un paramètre nouvellement ajouté. (Notez qu'une fois que les paramètres sont dans la portée de la page, ils sont également disponibles pour les modèles ou les vues inclus.) Par conséquent, j'ai vu le type de progression Boolean, alors que dans un exemple de base, il serait de type String.

TL / DR: soit supposer que les paramètres sont des chaînes, soit inclure explicitement des paramètres dans votre modèle de page lors du rendu.


1 commentaires

Merci! C'est logique :)