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

AJAX Discussion :

[AJAX] Mise à jour d'une variable


Sujet :

AJAX

  1. #1
    Membre régulier
    Inscrit en
    Octobre 2007
    Messages
    209
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 209
    Points : 120
    Points
    120
    Par défaut [AJAX] Mise à jour d'une variable
    Bonjour,
    Tout fonctionne à merveille sauf que :
    A l'aide de XMLHttpRequest nous chargeons dans deux "variables" (this.xmlTree et this.xsltTree) des données xml (dont la feuille de style xslt).
    Une méthode de l'objet, this.affiche() sert à afficher le résultat de la transformation.
    Le hic c'est que pour pouvoir afficher le résultat de la transformation,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this.laCible.innerHTML = this.xmlTree.transformNode(this.xsltTree);
    il faut générer une alerte !
    Et oui si avant la ligne de code ci-dessus il y a tout se passe à merveille sinon une erreur est produite signalant que this.xmlTree et que this.xsltTree sont undefined !
    Pourtant, Firebugg montre bien que le code xml et xslt ont bien étaient importés via thiscurrent.xsltTree = x.responseXML;
    Mon client évidemment ne veut pas de l'alerte et j'aimerais réussir l'opération sans elle.
    Sans doute alert() appelle-t-elle le coeur de l'appli est met les variables à jour ? Je pense que vous devriez pouvoir m'aider...
    Voici la partie du code :
    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
     
               function ObF8(){
    		this.leMessage = '';
    		this.ReReg = [];
    		this.xmlTree = null;
    		this.xsltTree = null;
    		this.laCible = document.getElementById('but');
    		this.al = 'Un instant';
                   this.F8traitement(but.name, veur);
    			this.F8xslt('/etXslt/chCli.xsl');
    			this.Affiche();
    		}
    	};
            ObF8.prototype.F8traitement = function(champ, valeur){
            //rien d'intéressant ici
            var x = ajx();
            var thiscurrent = this;//pour fermetures
            x.open("post", "ajax.php", true);
            x.onreadystatechange = function(){
                if((x.readyState == 4)&& (x.status == 200)){
                    thiscurrent.xmlTree = x.responseXML;
                }
            };
            x.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
            x.send(param);
        };
        ObF8.prototype.F8xslt = function(url){
            var x = ajx();
            var thiscurrent = this;//pour fermetures
            x.open("get", url, true);
            x.onreadystatechange = function(){
                if((x.readyState == 4)&& (x.status == 200)){
                    thiscurrent.xsltTree = x.responseXML;
                }
            };
            x.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
            x.send("");
        };
        ObF8.prototype.Affiche = function(){
            alert(this.al);//C'EST ICI ! SANS CETTE ALERTE RIEN NE MARCHE, AVEC TOUT FONCTIONNE 0 MERVEILLE...
            try{
                this.laCible.innerHTML = this.xmlTree.transformNode(this.xsltTree);
            }catch(exc){
                var xsltProc = new XSLTProcessor();
                xsltProc.importStylesheet(this.xsltTree);
                var fragment = xsltProc.transformToFragment(this.xmlTree, document);
                this.laCible.innerHTML = "";
                this.laCible.appendChild(fragment);
            }
        };
    Evidemment il est incomplet (200 lignes); mais il devrait vous aider à trouver le problème.
    Merci

  2. #2
    Membre expérimenté
    Avatar de gwyohm
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2007
    Messages
    925
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2007
    Messages : 925
    Points : 1 333
    Points
    1 333
    Par défaut
    Bonjour,

    Ton souci vient du fait que tu passes par une requête AJAX, et dans AJAX, il y a Asynchronous.

    Quand tu fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this.F8traitement(but.name, veur);
    tu lances une requete asynchrone, ce qui signifie que la ligne suivante s'execute alors que la requete vient juste d'etre envoyée, donc la réponse n'est probablement pas arrivée.

    Quand tu mets une alert, le temps que tu cliques sur le OK, la requete AJAX est terminée, la réponse traitée et tout fonctionne.

    Pour corriger ce problème, le plus simple est d'ajouter un callback à ta méthode F8traitement. Ce callback sera une fonction avec le code à executer quand la réponse sera arrivée, et après les traitements internes de la méthode :

    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
    ObF8.prototype.F8traitement = function(champ, valeur, callback){
            // on s'assure que callback ne soit pas undefined (au cas où il ne serait pas préciser) ou autre chose qu'une fonction
            if(typeof callback != "function") {
              callback = function(){};
            }
    
            var x = ajx();
            var thiscurrent = this;//pour fermetures
            x.open("post", "ajax.php", true);
            x.onreadystatechange = function(){
                if((x.readyState == 4)&& (x.status == 200)){
                    thiscurrent.xmlTree = x.responseXML;
                    callback();
                }
            };
            x.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
            x.send(param);
        };
    Ensuite, il faut modifier ton code d'appel pour qu'il exploite ce nouveau paramètre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    // il faut variabiliser this, sinon this n'est plus this dans la fonction callback
    var that = this;
    var onF8traitementFinished = function() {
      that.F8xslt('/etXslt/chCli.xsl');
      that.Affiche();
    }
    this.F8traitement(but.name, veur, onF8traitementFinished);

  3. #3
    Membre régulier
    Inscrit en
    Octobre 2007
    Messages
    209
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 209
    Points : 120
    Points
    120
    Par défaut
    Bonjour,
    Merci pour cette réponse fort habile.
    Toutefois, la modification effectuée, sans l'alerte : les données sont bien réceptionnées (on peut les voir dans Firebug) mais l'affichage du tableau ne se fait pas.
    Avec l'alerte tout fonctionne mais, nous ne voulons pas de l'alerte...
    Un progrès par rapport à ma version, grâce à l'apport de gwyohm c'est que ni this.xsltTree ni this.xmlTree ne sont mis sur undefined (un premier bug a donc bel et bien été corrigé) dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    try{
                this.laCible.innerHTML = this.xmlTree.transformNode(this.xsltTree);
            }catch(exc){
                var xsltProc = new XSLTProcessor();
                xsltProc.importStylesheet(this.xsltTree);
                var fragment = xsltProc.transformToFragment(this.xmlTree, document);
                this.laCible.innerHTML = "";
                this.laCible.appendChild(fragment);
            }
    Si vous pouviez aider à la suppression du vilain alert...
    Merci d'avance

  4. #4
    Membre régulier
    Inscrit en
    Octobre 2007
    Messages
    209
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 209
    Points : 120
    Points
    120
    Par défaut
    Merci gwyohm
    Le diagnostic était le bon.
    Simplement, en sus des améliorations fournies, le chargement (synchrone) de la feuille XSLT pouvant être fait avant on est sûr que lors de l'appel au données xml elle soit déjà chargée.
    Ainsi le code fonctionne et devient :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    var onF8traitementFinished = function() {that.Affiche();}
    this.F8xslt('/etXslt/chCli.xsl');
    this.F8traitement(but.name, veur, onF8traitementFinished);
    xslt est déjà chargée lorsque les appels asynchrones sont lancés...
    Merci

  5. #5
    Membre expérimenté
    Avatar de gwyohm
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2007
    Messages
    925
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2007
    Messages : 925
    Points : 1 333
    Points
    1 333
    Par défaut
    le chargement (synchrone) de la feuille XSLT pouvant être fait avant on est sûr que lors de l'appel au données xml elle soit déjà chargée
    Sauf que dans l'exemple donné, le chargement des xsl est asynchrone non ?

    Le problème est contourné en demandant la xsl avant le chargement du flux xml qui lui prend un callback. Mais le contournement ne va pas toujours suffir : rien ne garantit que le flux xml arrive après la xsl.

    pour garantir le résultat, il faudrait appliquer le même principe de callback pour le chargement du xsl.

    Cependant le traitement global sera plus long (sur mais plus long): les requêtes AJAX seront séquentielles. Pour permettre la parallélisation des requêtes, il faudrait un objet dédié qui se chargerait de vérifier la disponibilité des données...

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

Discussions similaires

  1. [AJAX] Mise à jour d'une variable php avec Ajax
    Par amine2208 dans le forum AJAX
    Réponses: 5
    Dernier message: 03/07/2014, 01h49
  2. Réponses: 4
    Dernier message: 21/11/2008, 16h02
  3. Mise à jour d'une variable après choix dans une combobox
    Par ~Brouette~ dans le forum Langage
    Réponses: 1
    Dernier message: 21/12/2007, 11h09
  4. [AJAX] Mise à jour d'une page après réception d'une requête
    Par M.Dlb dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 11/11/2006, 15h48
  5. Problème de mise à jour d'une variable
    Par Claire07 dans le forum Access
    Réponses: 2
    Dernier message: 19/06/2006, 21h40

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