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 :

Setter d'une propriété appelés dans la mauvaise phase?


Sujet :

JSF Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    179
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Octobre 2008
    Messages : 179
    Par défaut Setter d'une propriété appelés dans la mauvaise phase?
    Bonjour,

    mon problème du jour concerne une propriété de ma JSP dont j'ai l'impression que le setter (dans le bean) est appelé dans la mauvaise phase...
    Comme je ne commence que doucement à appréhender les différentes phases et leur manipulation, il est possible que j'aie commis une erreur de raisonnement.

    L'idée là est d'importer un fichier puis d'en afficher les résultats :
    • d'une part sous la forme d'une table
    • d'autre part sous la forme d'un changement de sélection courante dans une liste défilante


    Comme je dois prendre en compte les valeurs d'un certain nombre de champs de ma page avant de réaliser l'upload, je rempile l'événement associé au listener du fileupload afin de le déclencher dans la phase UPDATE_MODEL à la place de la ANY_PHASE (qui je suppose correspond à la phase"APPLY REQUEST VALUES").

    Jusque là ça fonctionne... sauf pour la mise à jour de la sélection courante : son setter (setField1CurrentCurrentValue()) est appelé après mon listener avec l'ancienne valeur de la page, et ce sans que la nouvelle valeur calculée aie été mise à jour dans ma page.

    J'ai tenté de déplacer mon événement plus loin (dans la phase "INVOKE_APPLICATION"), mais là encore le setter est de nouveau appelé après le listener, et vient écraser ma valeur fraîchement calculée.

    Je n'arrive pas à comprendre que celà fonctionne pour les champs de la table, et pas pour la sélection courante...

    Donc, si qqn a une idée pour éclairer ma lanterne vacillante...

    Code ci-dessous :
    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
    51
     
    <h:form id="form_Import"> 
      <rich:fileUpload
        id="upload" 
        acceptedTypes="csv" 
        fileUploadListener="#{monBean.fileUploadListener}">
        <a4j:support 	event="onuploadcomplete"
          oncomplete="SomeJavaScript();" 
          reRender="form_Import" /> />
        <a4j:support 	event="ontyperejected"
          oncomplete="ToggleSomeWarningMessage()" 
          reRender="errorField" />
      </rich:fileUpload>     
      <h:outputText visible="false" id="errorField" style="color: red" value=" "/>
     
      <a4j:region id="tableImportedRegion">
        <rich:extendedDataTable
          value="#{MyBean.importedFields}"
          var="importedFields"
          id="tableImportedFields">
          <f:facet name="caption">
            <h:outputText value="${bundle.some_caption}" />
          </f:facet>
          <rich:column
            width="0%"
            visible="false">
            <f:facet name="header">
              <h:outputText value="#{bundle.field_id}" />
            </f:facet>
            <h:outputText
            value="#{importedFields.id}"
            id="Id" />
          </rich:column>
          <rich:column width="11%">
            <f:facet name="header" >
              <h:selectOneMenu 
                value="#{MyBean.field1CurrentValue}">
                <f:selectItems value="#{MyBean.allPossibleValues}"/>
              </h:selectOneMenu>
            </f:facet>
            <h:outputText
              value="#{importedFields.field1}"/>
          </rich:column>
          <!-- same for Field2, 3, 4, ...-->
          <f:facet name="footer">
            <h:outputText value="#{bundle.some_footer_text}" />
          </f:facet>  
        </rich:extendedDataTable>
      </a4j:region>
     
    </h:form>
    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
        private int                     field1CurrentValue; // + getter/setter
        private List<SelectItem>        allPossibleValues;  // + getter/setter
     
     
        /**
         * Triggered once a file is uploaded.
         * 
         * @param event the upload event
         * @throws Exception the exception
         */
        public final void fileUploadListener(final UploadEvent event) throws Exception {
     
            final PhaseId phaseId = event.getPhaseId();
            if (phaseId.equals(PhaseId.ANY_PHASE)) {
                // In order to retrieve data updated from the model
                // we postpone the management of the file upload event
                event.setPhaseId(PhaseId.INVOKE_APPLICATION); // ou UPDATE_MODEL
                event.queue();
            } else if (phaseId.equals(PhaseId.INVOKE_APPLICATION)) {// ou UPDATE_MODEL
                myRawFile = event.getUploadItem().getData();
                loadImportedFields(myRawFile);
            }
        }
     
     
            /**
         * Loads the data to importedFields
         * 
         * @param data the imported fields
         * @throws Exception the exception
         */
        private void loadImportedFields(final String data) throws Exception {
            // MANY OPERATIONS 
            importedFields = doManyThings(); // => OK so far
            field1CurrentValue = getField1NewValueAccordingToImportedFields();
            // and so one for field 2, 3, ...
        }

  2. #2
    Rédacteur

    Profil pro
    Inscrit en
    Juin 2003
    Messages
    4 184
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 184
    Par défaut
    Bonjour,

    supprime a4j:region et réessaye..

  3. #3
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    179
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Octobre 2008
    Messages : 179
    Par défaut
    Bonjour, et merci de ton aide.

    J'avais déjà tenté d'enlever la région (j'ai oublié de le préciser, mea culpa) : ce n'aurait pas été la première fois que ce petit rien m'aurait posé un problème. Mais cette fois elle n'était pas coupable semblerait-il.
    Mon setter est toujours appelé après ET... (je viens seulement de m'en rendre compte) aussi avant.
    En somme, il est appelé deux fois, et chaque fois avec la valeur courante de la page, sans que celle-ci n'aie jamais été mise à jour

  4. #4
    Rédacteur

    Profil pro
    Inscrit en
    Juin 2003
    Messages
    4 184
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 184
    Par défaut
    Il est normal que le setter soit appelé plusieurs fois, c'est le fonctionnement de JSF, mais, pour quelle raison tu fais un traitement suivant la phase, il faut laisser le cycle JSF se dérouler normalement.
    Ajoute un a4j:support avec l’évènement onchange sur le selectOneMenu, comme ça la valeur sera automatiquement transféré au serveur, le bean soit être en scope session en request/keepAlive.

    Je ne sais pas si JSF gère deux évènements pour un même composant (ton fileUpload), tu peux vérifier s'il existe des erreurs ajax avec a4j:log

  5. #5
    Membre confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    179
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Octobre 2008
    Messages : 179
    Par défaut
    Citation Envoyé par Sniper37 Voir le message
    Il est normal que le setter soit appelé plusieurs fois, c'est le fonctionnement de JSF,
    Ce ne sont pas les appels multiples qui me dérangent, mais le fait que je pensais que le setter (et donc la màj de la propriété du bean depuis le composant) était appelé uniquement lors de la phase "UPDATE MODEL", donc APRES l'envoi de l'événement "onuploadcomplete" (qui lui est envoyé plus tôt, dans la phase de validation).

    Citation Envoyé par Sniper37 Voir le message
    mais, pour quelle raison tu fais un traitement suivant la phase, il faut laisser le cycle JSF se dérouler normalement.
    Ici c'est parceque mon traitement nécessite d'abord de récupérer les valeurs d'autres champs de ma page avant de gérer l'import. Hors comme précisé ci-dessus, l'événement "onuploadcomplete" intervient avant la phase UPDATE_MODEL : c'est pour ça que je reposte l'événement. L'idée m'avait déjà été suggérée pour un autre problème par koack ici , et se retrouve dans les propositions pour enrichir la FàQ ici

    Citation Envoyé par Sniper37 Voir le message
    Ajoute un a4j:support avec l’évènement onchange sur le selectOneMenu, comme ça la valeur sera automatiquement transféré au serveur, le bean soit être en scope session en request/keepAlive.
    Le bean est bien en scope session. Par contre l'ajout d'un support sur l'événement onchange n'apporte rien là... j'ai aussi essayé de sortir le selectone de la table, mais rien n'y fait.
    J'ai enfin essayé de déplacer la gestion de mon événement en toute fin, lors de la phase "RENDER_RESPONSE" (un moment de folie sans doute) : mais pas mieux évidemment... en bref, je patauge

    Citation Envoyé par Sniper37 Voir le message
    Je ne sais pas si JSF gère deux évènements pour un même composant (ton fileUpload), tu peux vérifier s'il existe des erreurs ajax avec a4j:log
    Ca ça a l'air ok : je n'ai pas d'erreur de ce côté là.
    Par contre j'ai bien des erreurs, mais je ne sais pas comment les identifier :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    error[12:00:49,897]: Error on parsing JSON data syntax error
    PS : je "prétends" beaucoup de choses, mais sans aucune prétention en fait : comme je le disais, je maîtrise encore très mal les différentes phases. Quand en plus s'en mêlent des composants qui ne respectent pas forcément le modèle que j'ai en tête, le chaos s'installe un peu là haut

  6. #6
    Rédacteur

    Profil pro
    Inscrit en
    Juin 2003
    Messages
    4 184
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 4 184
    Par défaut
    Citation Envoyé par Roger_Rabbit Voir le message
    Citation Envoyé par Sniper37 Voir le message
    Ajoute un a4j:support avec l’évènement onchange sur le selectOneMenu, comme ça la valeur sera automatiquement transféré au serveur, le bean soit être en scope session en request/keepAlive.
    Le bean est bien en scope session. Par contre l'ajout d'un support sur l'événement onchange n'apporte rien là... j'ai aussi essayé de sortir le selectone de la table, mais rien n'y fait.
    J'ai enfin essayé de déplacer la gestion de mon événement en toute fin, lors de la phase "RENDER_RESPONSE" (un moment de folie sans doute) : mais pas mieux évidemment... en bref, je patauge
    Si tu enlève le a4j:region, ajoute a4j:support, ça ne fonctionne pas ? poste le code..

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

Discussions similaires

  1. [Postsharp] Manager les getter et setter d'une propriété
    Par anthyme dans le forum Framework .NET
    Réponses: 4
    Dernier message: 13/01/2009, 11h19
  2. Créer une fonction appelée dans le contrôleur
    Par cissou06 dans le forum Ruby on Rails
    Réponses: 2
    Dernier message: 13/02/2008, 11h08
  3. Rendre une propriété visible dans VS2005
    Par frochard dans le forum ASP.NET
    Réponses: 2
    Dernier message: 25/10/2007, 14h20
  4. Réponses: 23
    Dernier message: 12/10/2007, 14h38
  5. Réponses: 10
    Dernier message: 20/09/2006, 12h53

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