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

JavaScript Discussion :

[AJAX] passer un argument a une fonction de callback ?


Sujet :

JavaScript

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 54
    Points : 30
    Points
    30
    Par défaut [AJAX] passer un argument a une fonction de callback ?
    Bonjour a tous,

    j'essaie de récupérer des coordonnées gps de villes avec google map. Je me prend la tête sur un bête petit problème :
    gclient.getLatLng, qui renvoie des coordonées d'après une chaine prend en argument une chaine de caractère et une fonction callback a laquelle elle envoie un objet GLatLng.
    J'essaie de faire passer un indice de tableau en plus de cet objet mais pas moyen...
    Les coordonnées s'affichent bien avec le alert alert("insee:"+" "+latln.lat()+","+latln.lng());
    mais le alert(i); m'indique "undefined"
    Quelqu'un aurait-il une solution ?
    Merci...

    PS : j'avais déjà essayer avec juste test(latln, i) à la place de function(latln, i){alert(i);test(latln, i)}) comme callback.


    Voici le code en question :

    Code javascript : 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
    function gmap_sql(responseObject)
    {
    	chaine = new Array();
    	var gclient = new GClientGeocoder;
    	for(var i=0; typeof(responseObject[i]) !="undefined"; i++)
    	{
    	var loader = document.createElement('div');
        loader.innerHTML = responseObject[i].chaine+" "+responseObject[i].insee ;
    	chaine[i] = responseObject[i].chaine ;
    	insee[i] = responseObject[i].insee ;
     
    //########## ICI #########
    	gclient.getLatLng(chaine[i]+" "+insee[i],function(latln, i){alert(i);test(latln, i)});
     
        document.getElementById("cont").appendChild(loader);
    	}
    }
    //Callback
    function test(latln,i)
    {
     
    alert("insee:"+" "+latln.lat()+","+latln.lng());
     
    }

  2. #2
    Membre expérimenté Avatar de DoubleU
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    1 106
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 106
    Points : 1 388
    Points
    1 388
    Par défaut
    Essaie ca:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var cb = function(_i)
    {
      return function(latln)
      {
        alert(_i)
        test(latln, _i);
      }
    }(i)
     
    gclient.getLatLng(chaine[i]+" "+insee[i],cb);

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 54
    Points : 30
    Points
    30
    Par défaut
    merci d'avoir répondu mais ça ne fonctionne pas (les alert ne se déclenchent pas)...
    J'ai trouvé quelque chose qui marche presque :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    for(var i=0; typeof(responseObject[i]) !="undefined"; i++)
    {
    ...
    gclient.getLatLng(chaine[i]+" "+insee[i],function(latln){
    			test(i,latln)});
    ...
    }
     
    function test(_i,latln)
    {
    alert(_i); 
    alert(latln.lat()+","+latln.lng());
    }
    Le gros problème, c'est que le alert(_i) m'affiche toujours le dernier indice du tableau. Je suppose que les fonctions callback sont stockées dans une pile d'appel et lorsque qu'elles démarrent la boucle for est déjà terminée donc i vaut le dernier indice...

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 54
    Points : 30
    Points
    30
    Par défaut
    autrement i doit passer par référence et pas par valeur...
    quelqu'un peut-il m'aider ?

  5. #5
    Membre expérimenté Avatar de DoubleU
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    1 106
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 106
    Points : 1 388
    Points
    1 388
    Par défaut
    Le gros problème, c'est que le alert(_i) m'affiche toujours le dernier indice du tableau. Je suppose que les fonctions callback sont stockées dans une pile d'appel et lorsque qu'elles démarrent la boucle for est déjà terminée donc i vaut le dernier indice...
    Normalement, la syntaxe que je t'ai donné résoud ce problème.
    Fais voir comment tu l'as retranscrite?

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 54
    Points : 30
    Points
    30
    Par défaut
    ça à l'air de fonctionner de cette manière :
    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
    function gmap_sql(responseObject)
    {
     
    	var gclient = new GClientGeocoder;
    	for(var i=0; typeof(responseObject[i]) !="undefined"; i++)
    	{
    	var loader = document.createElement('div');
        loader.innerHTML = responseObject[i].chaine+" "+responseObject[i].insee ;
    	chaine = responseObject[i].chaine ;
    	insee = responseObject[i].insee ;
    	  document.getElementById("cont").appendChild(loader);
    	  gclient.getLatLng(chaine[i]+" "+insee[i],
    		function(_i)
    		 {
    		  return function(latln)
    		  {
    		    test(latln, _i);
    		  }
    		}(i)
    		);
      }
     
    }
    function test(latln, _i)
    {
    alert(_i);
    alert("insee:"+" "+latln.lat()+","+latln.lng());
    lat= latln.lat();
    lng = latln.lng();
    Merci beaucoup, maintenant yapluka (enfin, j'espère)... !

    Par contre, je débute avec ce genre d'utilisation de javascript et je ne comprend pas la syntaxe (pourquoi ne passe-t-on pas latln dans la function callback ?, l'histoire du return function, et le paramètre qu'on passe avec (i))...
    Si tu sais où trouver un tutoriel là dessus, je suis preneur.

  7. #7
    Membre expérimenté Avatar de DoubleU
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    1 106
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 106
    Points : 1 388
    Points
    1 388
    Par défaut
    C'est vrai qu'au premier abord, c'est assez complexe ^^

    En fait, tu déclares une fonction qui va prendre en argument le ou les paramètres que tu veux passer, et tu l'exécutes immédiatement avec ces arguments
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    var f = function(_i)
    {
    // ..
    }(i)
    De cette façon, tu vas créer un contexte d'exécution qui va préserver ces variables pour tout le code que tu exécutes dans la fonction (c'est ce qui va te permettre par exemple d'éviter que ton i vaille toujours la dernière valeur dans ta boucle).

    Ensuite, à l'intérieur de cette fonction tu vas déclarer une fonction anonyme, avec en paramètres les arguments que le callback va te passer (un point je crois dans le cas de ton GClientGeocoder), qui va donc avoir accès aux variables du contexte que tu viens de créer, et tu la retournes de suite.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
      return function(latln)
      {
        alert(_i)
        test(latln, _i);
      }

    Comme ca, quand tu exécutes la ligne, tu crées bien un callback qui prend un seul argument et qui à accès à des variables qui seraient normalement hors de son contexte d'exécution.

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 54
    Points : 30
    Points
    30
    Par défaut
    Merci vraiment pour cette solution et son explication tu m'enleve une grosse épine du pied!

    Une dernière question si tu as le temps comme tu as l'air de maitriser le sujet.
    Voici maintenant 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
    function gmap_sql(responseObject)
    {
     
    	var gclient = new GClientGeocoder;
    	for(var i=0; typeof(responseObject[i]) !="undefined"; i++)
    	{
    	var loader = document.createElement('div');
        loader.innerHTML = responseObject[i].chaine+" "+responseObject[i].insee ;
    	chaine[i] = responseObject[i].chaine ;
    	//insee[i] = responseObject[i].insee ;
    	  document.getElementById("cont").appendChild(loader);
    	  gclient.getLatLng(chaine[i]+" "+responseObject[i].insee,
    		function(_insee, _i)
    		 {
    		  return function(latln)
    		  {
    		    test(latln, _insee, _i);
    		  }
    		}(responseObject[i].insee, i)
    		);
     
          }
    	setTimeout("timer()",3000);
    }
    function test(latln, _insee, _i)
    {
    lat[_i] = latln.lat();
    lng[_i] = latln.lng();
    insee[_i] = _insee;
    alert("i:"+_i+" insee:"+insee[_i]+" "+lat[_i]+","+lng[_i]);
    }
    function timer(){
    	alert("timer insee:"+insee[1]+" "+lat[1]+","+lng[1]);
    }
    Je rempli un des tableaux globaux pour ensuite les envoyer en ajax et faire une requete d'update.
    Je n'ai pas trouvé d'autre solution pour attendre la fin du remplissage des tableaux que le setTimeout... Ici c'est pas très génant car il s'agit d'un script que je n'executerai qu'une fois sur mon pc, avec un timeout large ça devrait passer.
    Mais j'imagine qu'il y a beaucoup plus propre pour faire du temps réel en production...
    Si tu as (ou quelqu'un d'autre aurait) une piste ?

  9. #9
    Membre expérimenté Avatar de DoubleU
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    1 106
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 1 106
    Points : 1 388
    Points
    1 388
    Par défaut
    Je ne suis pas sur d'avoir bien compris, mais si c'est ce que je pense, tu n'as qu'a rajouter un paramètre à ton callback pour lui dire s'il vient de traiter la dernière valeur de ton tableau. Dans ce cas, tu appelles ta fonction ajax pour faire ton update.

    Quelque chose dans ce genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    		function(_insee, _i, _isLast)
    		 {
    		  return function(latln)
    		  {
    		    test(latln, _insee, _i);
                        if(_isLast) 
                          doUpdate();
    		  }
    		}(responseObject[i].insee, i, i==responseObject.length)

  10. #10
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    54
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 54
    Points : 30
    Points
    30
    Par défaut
    ok ça marche nickel à part que c'est i==responseObject.length-1, l'indice du tableau commençant à 0.
    Encore une fois merci.
    Je ne suis pas encore très à l'aise avec les callbacks et autres threads, tes explications m'ouvrent les portes.

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

Discussions similaires

  1. [AC-2010] Passer un argument recordset à une fonction
    Par gagpie dans le forum VBA Access
    Réponses: 4
    Dernier message: 28/01/2016, 13h44
  2. Passer un argument dans une fonction appelée depuis un onChange
    Par francky74 dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 05/03/2015, 09h28
  3. Passer un argument a une fonction a traver URL
    Par sitirna dans le forum ASP.NET
    Réponses: 3
    Dernier message: 02/02/2009, 16h07
  4. Comment passer un argument dans une fonction
    Par DeezerD dans le forum ActionScript 3
    Réponses: 1
    Dernier message: 22/01/2008, 18h13
  5. Réponses: 9
    Dernier message: 19/10/2006, 10h02

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