web-dev-qa-db-fra.com

Essayer de comprendre immédiat = "vrai" en sautant les entrées alors qu'il ne devrait pas

Juste au moment où je pensais avoir compris immédiatement ... * soupir *

Considérez la page JSF suivante:

<h:inputText value="#{testBean.text}" required="true" />
<h:commandButton actionListener="#{testBean.doFoo}" value="Do Foo" />
<h:commandButton immediate="true" actionListener="#{testBean.doBar}" value="Do Bar" /><br />
<h:outputText value="#{testBean.didSomething}" />

Et ce grain de sauvegarde:

public class TestBean {
   private String didSomething = "Nothing done yet";
   // + getter

public void doFoo() {
    didSomething = "Did foo!";        
}

public void doBar() {
    didSomething = "Did bar!";        
}

De tout ce que j'ai lu immédiatement, je m'attendrais à ce qui suit:

  • Lorsque vous essayez de faire foo sans fournir de valeur pour le champ de saisie, l'action n'est jamais exécutée car pendant processValidationsPhase une erreur se produit, entraînant un nouveau rendu de la page directement après cette phase avec un message d'erreur. La valeur de didSomething reste inchangée. (Cela fonctionne comme prévu)

  • Lorsque vous essayez de faire une barre sans fournir de valeur pour le champ de saisie, l'action est exécutée pendant applyRequestValuesPhase en raison de l'attribut immédiat. La variable didSomething est modifiée. (Cela fonctionne comme prévu)

Sur ce qui se passe ensuite, cette description déclare:

"Une valeur de retour nulle (en tant que résultat de la méthode d'action) fait que le traitement se poursuit normalement, c'est-à-dire que les composants non immédiats sont validés puis le modèle de mise à jour est exécuté (si aucune erreur de validation ne s'est produite). Pour une méthode d'écoute d'action qui renvoie void, il est nécessaire d'appeler facesContext.renderResponse (); si le flux normal n'est pas souhaité. "

De là, j'ai eu l'idée que le traitement se poursuit normalement (car ma méthode d'action ne renvoie ni résultat ni force renderResponse()), ce qui entraîne la même erreur de validation. La seule différence serait qu'elle se produit après paramètre didSomething. Cependant, cela ne se produit pas. Au lieu de cela, il semble que le site ignore toujours toutes les phases restantes, le champ de saisie n'étant pas touché. Il est restitué sans message d'erreur.

Quelqu'un peut-il m'expliquer où ma compréhension de la façon dont cela fonctionne ne va pas?

22
Louise

Avec immediate="true" sur le bouton, l'action est en effet invoquée lors de la phase d'application des valeurs de requête et toutes les phases restantes sont ignorées. C'est aussi le seul point de cet attribut: traiter (décoder, valider, mettre à jour et invoquer) le composant immédiatement pendant la phase d'application des valeurs de demande.

Toutes les entrées qui ne pas ont immediate="true" sont de toute façon ignorés. Seules les entrées qui ont immediate="true" sont également traités, mais cela se produit également pendant la phase d'application des valeurs de demande. Pourquoi les phases restantes devraient-elles être appelées si tout a déjà eu lieu dans la phase d'application des valeurs de demande?

Dans l'article Debug JSF lifecycle vous pouvez trouver le résumé suivant qui devrait éclairer quand (ne pas) utiliser le immediate"true":

D'accord, quand dois-je utiliser l'attribut immédiat?

Si ce n'est pas encore tout à fait clair, voici un résumé, complet avec des exemples d'utilisation du monde réel quand ils peuvent être bénéfiques:

  • Si elle est définie dans UIInput (s) uniquement, la phase de validation du processus aura lieu dans la phase d'application des valeurs de demande à la place. Utilisez-le pour hiérarchiser la validation des composants UIInput en question. Lorsque la validation/conversion échoue pour l'un d'entre eux, les composants non immédiats ne seront pas validés/convertis.

  • Si elle est définie dans UICommand uniquement, la phase d'application des valeurs de demande jusqu'à ce que les phases de mise à jour des valeurs de modèle soient ignorées pour l'un des composants UIInput. Utilisez-le pour ignorer l'intégralité du traitement du formulaire. Par exemple. Bouton "Annuler" ou "Retour".

  • Si elle est définie dans les composants UIInput et UICommand, la phase d'application des valeurs de demande jusqu'à ce que les phases de mise à jour des valeurs du modèle soient ignorées pour tout composant UIInput qui ne le fait pas avoir cet attribut défini. Utilisez-le pour ignorer le traitement de l'ensemble du formulaire, attendez-vous à certains champs (avec immédiat). Par exemple. Bouton "Mot de passe oublié" dans un formulaire de connexion avec un champ de mot de passe obligatoire mais non immédiat.

Voir également:

37
BalusC