Bonjour,
J'ai vu ici une méthode pour ce faire mais qui, malheureusement ne fonctionne pas (ou du moins pas avec moi).
Je n'ai pas vu d'explication à ce sujet dans la FAQ. Y a-t-il une erreur dans la technique proposée ou une alternative ?
Merci.
Bonjour,
J'ai vu ici une méthode pour ce faire mais qui, malheureusement ne fonctionne pas (ou du moins pas avec moi).
Je n'ai pas vu d'explication à ce sujet dans la FAQ. Y a-t-il une erreur dans la technique proposée ou une alternative ?
Merci.
tu peux préciser ce que tu entends par "modifier les propriétés d'un managed bean?" Quelles propriétés, a quel moment et sous quelles conditions?
Salut,
Tout d'abord, merci pour ta réaction. Au fait, je désire vider les champs d'un formulaire dans une page jsf (ces champs sont bien entendus déclarés dans mon bean managé) plus précisement après sa validation. J'ai donc créé une classe Listener qui s'en charge.
Environnement : JBoss 5 / JSF 1.2 / Facelets / Richfaces 3.3.2 / Ajax4JSF
Page JSF (banque.xhtml)
Déclaration bean dans faces-config.xml
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 <h:form id="graphValidatorForm"> <a4j:region renderRegionOnly="true"> <rich:panel id="panel"> <f:facet name="header"> <h:outputText value="Ajout Banque" /> </f:facet> <rich:messages globalOnly="true" infoClass="msg_info" errorClass="msg_error" warnClass="msg_warn" /> <rich:graphValidator summary="Invalid values: "> <h:panelGrid columns="3"> <h:outputText value="Code :" /> <h:inputText id="banque_code" value="#{banqueBean.banqueVO.banque_code}" required="true"> <f:validator validatorId="banqueValidator"/> </h:inputText> <rich:message for="banque_code" showSummary="true" showDetail="false" /> <a4j:commandButton value="${msg['bouton.ajouter']}" id="ajouter"> <f:actionListener type="com.test.web.events.BanqueEvent"/> </a4j:commandButton> </f:facet> </h:panelGrid> </rich:graphValidator> </rich:panel> </a4j:region> </h:form>
BanqueBean
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 <managed-bean> <managed-bean-name>banqueBean</managed-bean-name> <managed-bean-class>com.test.web.beans.BanqueBean</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean>
BanqueVO
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 public class BanqueBean { private BanqueVO banqueVO = new BanqueVO(); public BanqueBean() { } public BanqueVO getBanqueVO() { return banqueVO; } public void setBanqueVO(BanqueVO banqueVO) { this.banqueVO = banqueVO; } public void effacer () { banqueVO.effacer(); } }
BanqueEvent (Listener)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 public class BanqueVO { private String banque_code; public BanqueVO() { } // etc ... Getter / Setter
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33 public class BanqueEvent implements ActionListener { @Override public void processAction(ActionEvent e) throws AbortProcessingException { String id = e.getComponent().getId(); // Contexte FacesContext ctx = FacesContext.getCurrentInstance(); System.out.println("--- processAction ---"); if (ctx != null) { // Bean BanqueBean banqueBean = (BanqueBean) ctx.getApplication().getExpressionFactory().createValueExpression(ctx.getELContext(), "#{banqueBean}", BanqueBean.class).getValue(ctx.getELContext()); // Action Ajout if (id.equals("ajouter")) { ctx.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Action Ajouter !", null)); } // Effacement ctx.getApplication().getExpressionFactory().createValueExpression(ctx.getELContext(), "#{banqueBean}", BanqueBean.class).setValue(ctx.getELContext(), null); System.out.println("--- Effacement ---"); } else System.out.println("--- ERREUR : Contexte null ! ---"); } }
bon bean est request scope, si tu but et d'afficher un formulaire vide après chaque action, il suffit de travailler correctement avec les règles de navigation, sans passer par tout ce chipotages:
Code : Sélectionner tout - Visualiser dans une fenêtre à part <a4j:commandButton value="${msg['bouton.ajouter']}" id="ajouter" action="#{banqueBean.ajouter}"/>
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 public class BanqueBean { //..... public String ajouter(){ // code de l'action return "AddDone"; } }Ainsi, après la réussite de l'action, la regle de navigation va entrer en vigeur. Le redirect va forcer le navigateur à redemander un page. Comme ton bean est request scope, il sera vide. Comme tu as fait un navigation, l'arbre JSF aussi sera vide (ce qui n'est pas le cas avec ton event, les composants gardant leur "submitted value" ! ). De plus, dans ton code, l'event n'est pas le meilleur endroit pour effectuer un action, c'est le role de l'action visée par le paramètre "action" du boutton
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 <navigation-rule> <from-view-id>/banqueAjouter.jsp</from-view-id> <navigation-case> <from-outcome>AddDone</from-outcome> <to-view-id>/banqueAjouter.jsp</to-view-id> <redirect/> </navigation-case> </navigation-rule>![]()
Au fait, dans mon exemple j'ai parlé de vider le formulaire mais cela reste un cas particulier. Ma question pour généraliser est au fait de savoir comment attribuer des valeurs aux attributs du bean et que cela soit répercuter au niveau Vue !
Ok. Tu me proposes une alternative. J'ai déjà testé cette solution et ça passe. Mais j'aimerais bien savoir comment procéder en passant par un Listener !
Que veux-tu dire par n'est pas le meilleur endroit ? peux être un peu plus précis ?
Merci.
l'event n'est qu'un intermédiaire, il n'a, pas exemple, aucun controle sur les regles de navigation, hors tu lui fait exécuter l'action et c'est l'action qui est censée diriger les règle de navigation.
Pour changer des propriétés d'un bean, c'est facile, il suffit d'appeler ses setters et getters, comme pour toute classe. Si ton problème est que la classe contenant l'event ne vois pas le bean, utilise les managed properties dans les faces-config.xml:
Pour ce qui est du formulaire, les valeurs soumisses par le client ont toujours priorité sur ce qui se trouve dans les beans. Et pour cause, JSF garanti à la fois de préserver les données pour les réafficher en cas de problème de validation et garanti que le bean ne sera pas mis a jour tant que la validation ne sera pas réussie. Autrement dit, sans navigation, le seul moyen de nettoyer le formulaire est moche et peu faciler à gérer: aller sur chaque composant héritant de UIInput et faire un setSubmittedValue(null)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 <managed-bean> <managed-bean-name>BanqueBean</managed-bean-name> <managed-bean-class>banqueBean</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>BanqueEventBean</managed-bean-name> <managed-bean-class>banqueEventBean</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> <managed-property> <property-name>banque</property-name> <value>#{banqueBean}</value> </managed-property> </managed-bean>
Partager