IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JSF Java Discussion :

CommandLink vers une autre page dans un DataTable


Sujet :

JSF Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre actif
    Développeur informatique
    Inscrit en
    Février 2007
    Messages
    70
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2007
    Messages : 70
    Par défaut CommandLink vers une autre page dans un DataTable
    Bonjour,

    J'essaye de me faire une petite application web en JSF pour me former au framework. J'ai un peu du mal à mettre en place ce que je veux. Je pense qu'il y a un truc que j'ai pas compris.

    J'ai une page avec un Datatable qui affiche des données provenant d'une BDD. Dans ce DataTable j'ai un commandLink qui permet de charger le détail complet des informations de mon objet et de les afficher dans une nouvelle page.

    Le code de la vue countries.xhtml (avec le datatable) :
    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
     
                      <h:form>
    			<h:dataTable value="#{countryBean.countries}" var="country" styleClass="countryTable" headerClass="countryTableHeader"
    				rowClasses="countryTableOddRow,countryTableEvenRow">
    				<h:column>
    					<f:facet name="header">
    						<h:outputText value="Code" />
    					</f:facet>
    					<h:outputText value="#{country.code}" />
    				</h:column>
    				<h:column>
    					<f:facet name="header">
    						<h:outputText value="Nom" />
    					</f:facet>
    					<h:outputText value="#{country.name}" />
    				</h:column>
    				<h:column>
    					<h:commandLink action="#{countryBean.showCountryDetails(country.code)}">
    						<img src="resources/images/loupe.png" width="20px" />
    					</h:commandLink>
    				</h:column>
    			</h:dataTable>
    		</h:form>
    Le code du ManagedBean :
    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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
     
    @ManagedBean
    @RequestScoped
    public class CountryBean implements Serializable {
        private static final long serialVersionUID = -7737871761357537657L;
        private CountryDTO selectedCountry;
        private List<CountryDTO> countries;
     
        @EJB
        private CountryServicesManager countryServicesManager;
     
        private static final Logger LOG = Logger.getLogger(CountryBean.class);
     
        public List<CountryDTO> getAllCountries() {
            return countryServicesManager.getAllCountries();
        }
     
        public String showCountryDetails(String code) {
            LOG.debug("code pays sélectionné = " + code);
            CountryDTO countryDTO = new CountryDTO();
            countryDTO.setCode(code);
            countryDTO.setContinent("continent");
            countryDTO.setName("countryName");
            countryDTO.setPopulation(100000);
            countryDTO.setSurface(1000033787.98);
            selectedCountry = countryDTO;
            return "countryDetails";
        }
     
     
        public CountryDTO getSelectedCountry() {
            return selectedCountry;
        }
     
        public void setSelectedCountry(CountryDTO selectedCountry) {
            this.selectedCountry = selectedCountry;
        }
     
    	public List<CountryDTO> getCountries() {
    		if (countries==null) {
    			countries = getAllCountries();
    		}
    		return countries;
    	}
     
    	public void setCountries(List<CountryDTO> countries) {
    		this.countries = countries;
    	}
     
    }
    Le code de ma 2ème page qui affiche simplement le détail d'un pays :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
                    <p><span class="label">Code : </span> <h:outputText value="#{countryBean.selectedCountry.code}"/></p>
    		<p><span class="label">Continent : </span> <h:outputText value="#{countryBean.selectedCountry.continent}"/></p>
    		<p><span class="label">Surface : </span> <h:outputText value="#{countryBean.selectedCountry.surface}"/></p>
    		<p><span class="label">Nombre d'habitants : </span> <h:outputText value="#{countryBean.selectedCountry.population}"/></p>
    		<br/>
    		<p><pretty:link mappingId="countries">Retour à la liste des pays</pretty:link></p>
    Ce que je ne comprend pas c'est que quand je passe en debug dans ma méthode getCountries je remarque qu'elle est appelée de nombreuses fois. Pourquoi ? Elle devrait être appelée une seul fois lorsque la page countries.xhtml est chargée non ?
    De plus quand je clique sur mon commandLink pour charger la page de détail à partir du code pays de la ligne choisie, je remarque que ma méthode getCountries est de nouveau exécutée et cela avant même que la méthode showCountryDetails (l'action de mon commandLink) ne soit appelée. Est-ce que je m'y prend mal ?

    Merci d'avance pour votre aide.

    EDIT : J'ai oublié de préciser que j'utilise MyFaces version 2.2.5. L'application est déployée dans un serveur glassfish version 4.1.

  2. #2
    Membre expérimenté
    Homme Profil pro
    Développeur Java/JavaEE
    Inscrit en
    Août 2014
    Messages
    194
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Développeur Java/JavaEE

    Informations forums :
    Inscription : Août 2014
    Messages : 194
    Par défaut
    Bonjour,

    C'est la première fois que je découvre le chargement du modèle depuis le getter ça semble correcte mais a elle impacte à ton problème?? Ce que je te conseil c'est de ne plus chargé ton modèle avec la méthode get mais plutôt de le charger depuis ton constructeur ou plus encore à travers l'annotation @postcontrcut qui se déclenche lors de la création de ton bean.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    @PostConstruct
    	public void init(){
    		countries = getAllCountries();
    	}

  3. #3
    Membre actif
    Développeur informatique
    Inscrit en
    Février 2007
    Messages
    70
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2007
    Messages : 70
    Par défaut
    Merci pour ta réponse Maine13.

    En fait au début j'initialisais mon datatable en appelant directement la méthode getAllCountries. Du coups je n'avais même pas besoin d'avoir la liste an variable d'instance de mon CountryBean. Quand j'ai vus que la méthode était appelée plusieurs fois j'ai changé de façon de faire pour que getAllCountries ne soit appelée qu'une seule fois à chaque chargement.

    J'ai pensé aussi à faire le chargement dans le PostConstruct. Mais je me dis que ca va être le même problème. Quand je vais vouloir charger le détail d'un pays le Bean va exécuter à nouveau le PostConstruct (vu que je suis en scope request) et du coups getAllCountries sera chargée à nouveau alors qu'il n'y en a pas besoin. Et je ne veux pas mettre ScopeSession comme je le vois dans beaucoup de tuto sur le web parce que il n'y en a pas l'utilité selon moi.

    Est-ce qu'il faut que je fasse un ManagedBean par écran ? En fait j'essaye de savoir qu'elle est la bonne pratique pour gérer ce genre de cas ?

  4. #4
    Membre actif
    Développeur informatique
    Inscrit en
    Février 2007
    Messages
    70
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2007
    Messages : 70
    Par défaut
    J'ai finalement réussi à faire ce que je voulais sans que la liste des pays soit rechargé inutilement.

    J'ai créé un deuxième ManagedBean contenant une variable d'instance "selectedCountry" qui est chargé à partir de ma méthode showCountryDetails. Ainsi il y a un bean pour chaque écran.
    Je charge à présent la liste des pays dans une méthode init annotée @PostConstruct comme conseillé par Maine13.

    Ce que je ne comprends pas toutefois c'est que j'ai du mettre le scope du premier bean à ViewScoped pour pas que la méthode init soit exécutée lorsque l'utilisateur clique sur le commandLink.
    Pourquoi mon "CountryBean" est rechargé quand je clique sur le commandLink alors que l'action est effectuée sur un autre Bean ?

    Voila à quoi ressemble le commandLink à présent :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
     <h:commandLink action="#{countryDetailsBean.showCountryDetails(country.code)}">
    	 <img src="resources/images/loupe.png" width="20px" />
     </h:commandLink>

  5. #5
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Parce que JSF travaille avec un Cycle de vie. Quand tu clique sur le lien, le formulaire est soumis, il se passe ceci coté serveur:

    la vue est scannée une fois pour appliquer les valeur soumise
    la vue est scannée une deuxième fois pour valider les valeurs et les convertire
    la vue est scannée une troisième fois pour transférer les données vers les backing beans
    l'action est exécutée
    la vue final est scannée pour générer la réponse.

    Donc tous les beans impliqués dans ta vue sont impliqués lors du commandLink, car avant d'arriver à exécuter ton action il faut prendre le formulaire, le valider, le transférer vers les beans et seulement si tout s'est bien passée, exécuter l'action.

  6. #6
    Membre actif
    Développeur informatique
    Inscrit en
    Février 2007
    Messages
    70
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2007
    Messages : 70
    Par défaut
    Merci tchize_ pour tes explications. Je suis au courant pour le cycle de vie du bean, mais ce que je comprenais pas c'est pourquoi il a besoin de charger à nouveau le backing bean.

    D'après toi est-ce que la solution que j'ai décrit dans mon précédent post est la bonne ? Moi ce qui ne me plait pas c'est de mettre un "ViewScoped" sur mon premier bean. Ce que j'avais cru comprendre c'est que ce scope était normalement utilisé pour les écrans "ajaxisé", ce qui n'est pas le cas ici.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. transfert d'un script qui est dans une iframe vers une autre page
    Par brunochp dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 10/03/2009, 16h14
  2. Redirect vers une autre page
    Par RobinNono dans le forum Langage
    Réponses: 5
    Dernier message: 24/08/2006, 15h01
  3. Lien vers une autre page puis qui selection d'un elt d'une listbox
    Par avogadro dans le forum Général JavaScript
    Réponses: 8
    Dernier message: 12/08/2006, 13h03
  4. [PHP-JS] Rediriger vers une autre page
    Par Vlacar dans le forum Langage
    Réponses: 13
    Dernier message: 10/04/2006, 13h23
  5. iis redirection vers une autre page
    Par wodel dans le forum IIS
    Réponses: 1
    Dernier message: 03/01/2006, 15h36

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo