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] return fonction onreadystatechange


Sujet :

AJAX

  1. #1
    Membre confirmé
    Inscrit en
    Avril 2010
    Messages
    200
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 200
    Par défaut [AJAX] return fonction onreadystatechange
    Bonjour à tous,

    Je fais actuellement une requête ajax vers mon serveur, retourne les valeurs au format JSON, et construit un tableau suivant les valeurs avec DOM...
    A côté de ça mon problème a l'air ridicule mais je n'arrive pas à le résoudre !

    Je vous montre d'abord mon 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
    51
    52
    53
    54
    55
    56
    57
    param_tests_jmeter.Ajax = {
     
        jspFolder : '/ParamTestJMeter-portlet/jsp',
     
        getTests : function() {
            var xhr = this.getXhr();
            if (xhr === null) {
                alert("Your browser doesn't support XMLHttpRequest!");
                return;
            }
     
            var url = this.jspFolder+'/dynamic_request/getJMeterTests.jsp';
     
            // fonction appelée lors d'un changement d'état de la requête (de traitementMethods.jsp)
            xhr.onreadystatechange = function() {
                param_tests_jmeter.Ajax.stateChanged(xhr);
            };
            xhr.open("GET",url,true);
            xhr.send(null);
        },
     
        stateChanged : function(xhr) {
            // On vérifie que le requête s'est bien effectuée avant de continuer
            if (xhr.readyState === 4 &&
                xhr.status === 200) {
                // évaluation du message JSON (eval())
                var tableauValeurs = eval("(" + xhr.responseText + ")");
     
                //Construction de mon tableau
                param_tests_jmeter.Table.createTable('div_edit_table_jmeter');
                var imax = tableauValeurs.length;
                for (var i = 0; i < imax; i++)
                    param_tests_jmeter.Table.addRow(tableauValeurs[i].name,
                                                    tableauValeurs[i].environment,
                                                    tableauValeurs[i].description,
                                                    tableauValeurs[i].fileName,
                                                    tableauValeurs[i].isActive);
            }
        },
     
        // récupération de l'objet XmlHttpRequest (ajax) permettant d'échanger des informations
        getXhr : function() {
            var xhr;
            try {
                // Firefox, Opera 8.0+, Safari
                xhr = new XMLHttpRequest();
            } catch (e) {
                // Internet Explorer
                try {
                    xhr = new ActiveXObject('Msxml2.XMLHTTP');
                } catch (e) {
                    xhr = new ActiveXObject('Microsoft.XMLHTTP');
                }
            }
            return xhr;
        }
    };
    mon problème donc et que j'aimerais faire un return de tableauValeurs pour pouvoir construire mon tableau hors de la fonction statechanged...
    Le problème vous l'aurez deviné, c'est que si je fais ceci, ma construction du tableau s'exécute avant même d'avoir reçu les résultats.

    J'ai tenté en synchrone avec le paramètre à false, mais c'est pas convaincant !

    J'avais cru voir qu'on avait pas trop le choix et qu'on devait faire nos actions dans la fonction, mais je n'y crois pas ! Il y a forcément une solution !? Nan ?

  2. #2
    Membre Expert
    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
    Par défaut
    Bonjour,

    Il faut que tu passes une fonction en paramètre à stateChanged, qui pointe vers la fonction qui fait les traitements particuliers à la requete ajax. C'est le principe du callback :

    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
     
    var dessineTableau = function(xhr) {
      // évaluation du message JSON (eval())
      var tableauValeurs = eval("(" + xhr.responseText + ")");
      //Construction de mon tableau
      param_tests_jmeter.Table.createTable('div_edit_table_jmeter');
      var imax = tableauValeurs.length;
      for (var i = 0; i < imax; i++)
      param_tests_jmeter.Table.addRow(tableauValeurs[i].name,
        tableauValeurs[i].environment,
        tableauValeurs[i].description,
        tableauValeurs[i].fileName,
        tableauValeurs[i].isActive);
    }
    // ...
    stateChanged : function(xhr, callback) {
      if (xhr.readyState === 4 &&
                xhr.status === 200) {
                callback(xhr);
      }
    }
    // ...
    getTests : function() {
            var xhr = this.getXhr();
            if (xhr === null) {
                alert("Your browser doesn't support XMLHttpRequest!");
                return;
            }
     
            var url = this.jspFolder+'/dynamic_request/getJMeterTests.jsp';
     
            // fonction appelée lors d'un changement d'état de la requête (de traitementMethods.jsp)
            xhr.onreadystatechange = function() {
                param_tests_jmeter.Ajax.stateChanged(xhr, dessineTableau );
            };
            xhr.open("GET",url,true);
            xhr.send(null);
        }
    Tu gardes ainsi une encapsulation de xhr qui reste générique

  3. #3
    Membre confirmé
    Inscrit en
    Avril 2010
    Messages
    200
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 200
    Par défaut
    Bonjour gwyohm,

    Merci de ta réponse.

    J'ai mis en place ton code (en le modifiant un tout petit peu) et ça fonctionne !

    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
    getTests : function() {
            var xhr = this.getXhr();
            if (xhr === null) {
                alert("Your browser doesn't support XMLHttpRequest!");
                return;
            }
     
            var url = this.jspFolder+'/dynamic_request/getJMeterTests.jsp';
     
            // fonction appelée lors d'un changement d'état de la requête
            xhr.onreadystatechange = function() {
                jmeter_param_tests.Ajax.stateChanged(xhr, jmeter_param_tests.Ajax.displayTable);
            };
            // les paramètres sont envoyés en GET : inutile de passer en POST étant donné
            // que ces valeurs seront de toute façon affichées à l'utilisateur.
            xhr.open("GET",url,true);
            xhr.send(null);
        },
     
        stateChanged : function(xhr, callback) {
            // On vérifie que le requête s'est bien effectuée avant de continuer
            if (xhr.readyState === 4 &&
                xhr.status === 200) {
     
                // évaluation du message JSON (eval())
                callback(eval("(" + xhr.responseText + ")"));
            }
        },
     
        displayTable : function(tableValue) {
            //Construction de mon tableau
            jmeter_param_tests.Table.createTable('jmeter_div_edit_table');
     
            var imax = tableValue.length;
            for (var i = 0; i < imax; i++)
                jmeter_param_tests.Table.addRow(tableValue[i].name,
                                                tableValue[i].environment,
                                                tableValue[i].description,
                                                tableValue[i].fileName,
                                                tableValue[i].isActive);
        },
    la fonction displayTable est bien indépendante du reste !

    Cependant la fonction getTests me dérange un petit peu... Parce qu'en l'état actuel, si je veux faire une autre requête Ajax il faut que je créé une autre fonction et donc remettre tout le contenu de getText, il faut juste modifier l'url et la fonction... Ne peut-on pas faire encore plus générique ? Tu vois ce que je veux dire ?

    Sinon concernant le code en lui même as-tu des suggestions ?

  4. #4
    Membre Expert
    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
    Par défaut
    et bien getTests peut prendre en paramètres l'url et la fonction...
    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
     
    getTests : function(url, callback) {
            var xhr = this.getXhr();
            if (xhr === null) {
                alert("Your browser doesn't support XMLHttpRequest!");
                return;
            }
     
            var url = this.jspFolder+url;
     
            // fonction appelée lors d'un changement d'état de la requête
            xhr.onreadystatechange = function() {
                jmeter_param_tests.Ajax.stateChanged(xhr, callback);
            };
            // les paramètres sont envoyés en GET : inutile de passer en POST étant donné
            // que ces valeurs seront de toute façon affichées à l'utilisateur.
            xhr.open("GET",url,true);
            xhr.send(null);
        }

  5. #5
    Membre confirmé
    Inscrit en
    Avril 2010
    Messages
    200
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 200
    Par défaut
    Oui justement en cherchant un peu je suis tombé sur :
    http://www.developpez.net/forums/d65...pel-generique/

    Donc ça revient un peu à ce qu'on est en train de faire mais il reste un petit problème sur la fonction passé en paramètre... Peut-on passer les paramètres de la fonction passé en paramètre en même temps ?

    Parce qu'à l'appel de la fonction callback, il se peut que je veuille utiliser plusieurs fonction avec plusieurs paramètres...

  6. #6
    Membre Expert
    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
    Par défaut
    Tu vas finir par t'écrire un framework... c'est peut-être plus simple d'en utiliser un existant... (et je ne dis pas ça parce que je n'ai fait que regarder comment c'était fait dans prototype...)

    Le but est en fait de définir des paramètres à une fonction sans l’exécuter tout de suite: on veut obtenir une nouvelle fonction qui contient la première pré-paramétrer et passer le(s) dernier(s) paramètre(s) au dernier moment...

    alors on peut wrapper notre fonction dans une autre, mais de façon plus générique, tu peux faire quelque chose comme ça :

    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
     
    var getPresetFunction = function() {
     // si on n'a aucun parametre, ca ne va pas...
     if(arguments.length < 1) throw "pas de fonction à préparer...";
     // on recupere la fonction
     var _function  = arguments[0];
     // on fait une copie des paramètres sauf le premier qui est la fonction
     // on doit passer par Array.prototype.slice car arguments n'est pas un vrai Array
     var args = Array.prototype.slice.call(arguments, 1);
     // on renvoie une nouvelle fonction qui lors de son appel concatène 
     // les paramètres reçus à ceux reçus par getPresetFunction 
     return function() {
       var params = args.concat(Array.prototype.slice.call(arguments, 0));
       return _function.apply(this, params);
     };
    }
    // teste:
    var myAlert=function() {
      for(var i=0, length=arguments.length; i<length; i++) {
        alert(arguments[i]);
      }
    }
    myAlert("a"); //=> "a"
    myAlert("a", "b"); //=> "a" puis "b"
     
    var myPreparedAlert = getPresetFunction(myAlert, "c", "d");
    myPreparedAlert("e", "f"); // => "c" puis "d" puis "e" puis "f"
    Après tu peux faire quelque chose de plus pratique :
    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
     
    Function.prototype.prepare = function() {
     // si on n'a aucun parametre,on renvoie la fonction... c'est this
     if(arguments.length==0) return this;
     // on recupere la fonction
     var _function  = this;
     // on fait une copie des paramètres 
     // on doit passer par Array.prototype.slice car arguments n'est pas un vrai Array
     var args = Array.prototype.slice.call(arguments, 0)
     return function() {
       var params = args.concat(Array.prototype.slice.call(arguments, 0));
       return _function.apply(this, params);
     }
    };
    // teste:
    var myAlert2=function() {
      for(var i=0, length=arguments.length; i<length; i++) {
        alert(arguments[i]);
      }
    }
    myAlert2("a"); //=> "a"
    myAlert2("a", "b"); //=> "a" puis "b"
     
    var myPreparedAlert2 = myAlert2.prepare("c", "d");
    myPreparedAlert("e", "f"); // => "c" puis "d" puis "e" puis "f"
    De cette façon, tu peux préparer tes fonctions de retour avec des paramètres, la transmettre à ton encapsulation de xhr qui ajoutera le dernier parametre : la réponse texte

  7. #7
    Membre confirmé
    Inscrit en
    Avril 2010
    Messages
    200
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 200
    Par défaut
    Tu vas finir par t'écrire un framework... c'est peut-être plus simple d'en utiliser un existant... (et je ne dis pas ça parce que je n'ai fait que regarder comment c'était fait dans prototype...)
    Oui j'ai bien l'impression, mais bon au moins ça me fait apprendre !

    Pour le reste, j'ai compris le principe, mais lorsque tu fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var myPreparedAlert2 = myAlert2.prepare("c", "d");
    myPreparedAlert("e", "f"); // => "c" puis "d" puis "e" puis "f"
    Je comprends pas vraiment... Tu prépares une fonction avec des paramètres que t'appelles via une fonction qui fait qu'afficher les arguments...
    ... Pas compris !

    Ensuite comment la passer dans la fonction xhr ?

    Etant donné que c'est un prototype, j'ai du mettre la fonction hors de ma classe...

    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
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    jmeter_param_tests.Ajax = {
     
        jspFolder : '/ParamTestJMeter-portlet/jsp',
     
        getTests : function(url, callback) {
            var xhr = this.getXhr();
            if (xhr === null) {
                alert("Your browser doesn't support XMLHttpRequest!");
                return;
            }
     
            var urlToSend = this.jspFolder+url;
     
            // fonction appelée lors d'un changement d'état de la requête
            xhr.onreadystatechange = function() {
                jmeter_param_tests.Ajax.stateChanged(xhr, callback);
            };
            // les paramètres sont envoyés en GET : inutile de passer en POST étant donné
            // que ces valeurs seront de toute façon affichées à l'utilisateur.
            xhr.open("GET", urlToSend, true);
            xhr.send(null);
        },
     
        stateChanged : function(xhr, callback) {
            // On vérifie que le requête s'est bien effectuée avant de continuer
            if (xhr.readyState === 4 &&
                xhr.status === 200) {
     
                // évaluation du message JSON (eval())
                callback(eval("(" + xhr.responseText + ")"));
            }
        },
     
        // récupération de l'objet XmlHttpRequest (ajax) permettant d'échanger des informations
        getXhr : function() {
            var xhr;
            try {
                // Firefox, Opera 8.0+, Safari
                xhr = new XMLHttpRequest();
            } catch (e) {
                // Internet Explorer
                try {
                    xhr = new ActiveXObject('Msxml2.XMLHTTP');
                } catch (e) {
                    xhr = new ActiveXObject('Microsoft.XMLHTTP');
                }
            }
            return xhr;
        }
    };
     
    Function.prototype.prepare = function() {
         // si on n'a aucun parametre,on renvoie la fonction... c'est this
         if(arguments.length==0) return this;
         // on recupere la fonction
         var _function  = this;
         // on fait une copie des paramètres 
         // on doit passer par Array.prototype.slice car arguments n'est pas un vrai Array
         var args = Array.prototype.slice.call(arguments, 0)
         return function() {
           var params = args.concat(Array.prototype.slice.call(arguments, 0));
           return _function.apply(this, params);
         };
    };

  8. #8
    Membre Expert
    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
    Par défaut
    Citation Envoyé par Air P-E Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var myPreparedAlert2 = myAlert2.prepare("c", "d");
    myPreparedAlert("e", "f"); // => "c" puis "d" puis "e" puis "f"
    Je comprends pas vraiment... Tu prépares une fonction avec des paramètres que t'appelles via une fonction qui fait qu'afficher les arguments...

    Ensuite comment la passer dans la fonction xhr ?
    Le but est de répondre à ta question : comment ajouter d'autres paramètres à la fonction traitant le retour de la requète AJAX :

    Admettons que tu aies une fonction générique pour le traitement des réponses ajax handleAjaxResponse. Cette fonction prend un ensemble de paramètres dont le dernier est la réponse de xhr.

    Au moment de l'appel à getTests, tu vas fournir handleAjaxResponse en callback. Simplement, getTests va appeler handleAjaxResponse en lui passant le responseText de la réponse AJAX ; dans un de tes précédents messages, tu dis vouloir donner d'autres paramètres à cette fonction.

    Tu peux le faire en utilisant le code que je t'ai envoyé :
    tu preset à ta fonction handleAjaxResponse un ensemble de paramètre, tu passes cette nouvelle fonction à getTest et lors de l'appel la reponse texte sera ajoutée aux paramètres avant l'appel à handleAjaxResponse

  9. #9
    Membre confirmé
    Inscrit en
    Avril 2010
    Messages
    200
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 200
    Par défaut
    Le but est de répondre à ta question : comment ajouter d'autres paramètres à la fonction traitant le retour de la requète AJAX :
    Oui je sais merci !

    J'avais compris le principe mais pas trop comment l'utiliser...

    Mais avec ce que tu as dit ensuite :

    Admettons que tu aies une fonction générique pour le traitement des réponses ajax handleAjaxResponse. Cette fonction prend un ensemble de paramètres dont le dernier est la réponse de xhr.

    Au moment de l'appel à getTests, tu vas fournir handleAjaxResponse en callback. Simplement, getTests va appeler handleAjaxResponse en lui passant le responseText de la réponse AJAX ; dans un de tes précédents messages, tu dis vouloir donner d'autres paramètres à cette fonction.

    Tu peux le faire en utilisant le code que je t'ai envoyé :
    tu preset à ta fonction handleAjaxResponse un ensemble de paramètre, tu passes cette nouvelle fonction à getTest et lors de l'appel la reponse texte sera ajoutée aux paramètres avant l'appel à handleAjaxResponse
    J'ai mieux compris, j'ai d'ailleurs réussi à le mettre en place !
    J'ai un petit peu galérer je dois l'avouer, mais bon c'est bon je suis arrivé au bout !

    Résolu !

    Merci beaucoup à toi !

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

Discussions similaires

  1. [AJAX] Rappel fonction ajax
    Par Phenomenium dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 24/01/2007, 16h02
  2. [AJAX] Une fonction pour poster un formulaire?
    Par Mysti¢ dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 07/09/2006, 18h28
  3. [AJAX] ajax et fonction javascript
    Par locs dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 24/08/2006, 16h56
  4. [Ajax] question avec onreadystatechange
    Par lhulard dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 06/06/2006, 14h46
  5. [AJAX] Ma fonction ne se termine pas...
    Par Davboc dans le forum Général JavaScript
    Réponses: 17
    Dernier message: 08/03/2006, 12h05

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