Précédent   Forum des professionnels en informatique > Webmasters - Développement Web > JavaScript
JavaScript Forum programmation JavaScript. Lire : Cours JavaScript, FAQ JavaScript, Toutes les FAQ JavaScript et Sources JavaScript
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
Vieux 05/07/2009, 18h41   #1
Invité régulier
 
Inscription : avril 2004
Messages : 61
Détails du profil
Informations forums :
Inscription : avril 2004
Messages : 61
Points : 9
Points : 9
Par défaut Requête Access via PHP/XML

Yop,

je suis en train de faire une petite api pour gérer un stock là où je travaille, et j'ai un petit soucis lors de l'appel à la BDD.
En fait tout fonctionne bien. Pour vous expliquer voici le code:
Code :
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
 
function ajax(num, arg)
{
    var xhr=null;
 
    if (window.XMLHttpRequest) { 
        xhr = new XMLHttpRequest();
    }
    else if (window.ActiveXObject) 
    {
        xhr = new ActiveXObject("Microsoft.XMLHTTP");
    }
 
    var ii = [];
    xhr.onreadystatechange = function() { 
        if (xhr.readyState==4) 
        {
	        var	docX = xhr.responseXML;
	        var items = docX.getElementsByTagName("rep");
	        if (items.length != 0){
		        for (i=0;i<items.length;i++)
		      	{
			      	ii[i] = items[i].getAttribute("ii");
		      	}
	        }
		    else
		        {alert("rien trouvé");}
        }
    };
    xhr.open("GET", "requete_mysql_xml.php?num=" + num + "&arg=" + arg, true);
    xhr.send(null);
    var i = 0;
//	while (ii.length == 0) {}
    return ii;
}
En gros tout à la fin vous pouvez voir que j'ai mis un "while", et ce parce que sinon le code continue à s'exécuter sans que xhr.readystate soit à 4, et par conséquence sans que mes données soient récupérées depuis la bdd.
Le problème là dedans c'est que ça fait bugger le navigateur, et là en particulier il me demande à chaque fois si je veux arrêter le script gourmand.

Donc voilà, j'aurais aimé savoir si vous connaissiez une parade à ça

Merci d'avance
A+
saipas
saipas est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/07/2009, 00h22   #2
Expert Confirmé
 
Avatar de emmanuel.remy
 
Emmanuel REMY
Inscription : novembre 2005
Messages : 2 826
Détails du profil
Informations personnelles :
Nom : Emmanuel REMY
Âge : 43

Informations forums :
Inscription : novembre 2005
Messages : 2 826
Points : 3 560
Points : 3 560
Salut,

Ton code est correct, et ta requête AJAX est asynchrone, d'où la continuité d'exécution, et la fonction de rappel onreadystatechange. Ton souci c'est que ta variable ii est locale à ta fonction . Plutôt ce code::
Code :
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
 
var ii = [];
function ajax(num, arg)
{
    var xhr=null;
 
    if (window.XMLHttpRequest) { 
        xhr = new XMLHttpRequest();
    }
    else if (window.ActiveXObject) 
    {
        xhr = new ActiveXObject("Microsoft.XMLHTTP");
    }
 
    xhr.onreadystatechange = function() { 
        if (xhr.readyState==4) 
        {
	        var	docX = xhr.responseXML;
	        var items = docX.getElementsByTagName("rep");
	        if (items.length != 0){
		        for (i=0;i<items.length;i++)
		      	{
			      	ii[i] = items[i].getAttribute("ii");
		      	}
	        }
		    else
		        {alert("rien trouvé");}
        }
    };
    xhr.open("GET", "requete_mysql_xml.php?num=" + num + "&arg=" + arg, true);
    xhr.send(null);
}
dès que ta requête AJAX a fini et récupéré ses données, alors ton tableau ii est accessible.

ERE
__________________
Quand une tête pense seule, elle devient folle.
emmanuel.remy est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/07/2009, 00h36   #3
Invité régulier
 
Inscription : avril 2004
Messages : 61
Détails du profil
Informations forums :
Inscription : avril 2004
Messages : 61
Points : 9
Points : 9
Salut Emmanuel,

merci pour ta réponse.
Je crois que ton astuce ne convient pas tout à fait au reste de mon code. En gros la fonction ajax (renommée fetchSQL depuis :p) se trouve dans un .js, et est appelée directement par la page (comme tu t'en doutes) avec un truc du genre :
Code :
1
2
3
4
5
6
7
 
	var rslt = fetchSQL(num, arg);
    for (i=0;i<rslt.length;i++)
  	{
      	nv = new Option(rslt[i]);
      	document.getElementById('selectObj').options[document.getElementById('selectObj').length] = nv;
  	}
Donc voilà, si j'utilise une variable globale ii ne vais-je pas avoir du mal pour la suite de l'exécution, qui affiche le résultat de la requête sur ma page?

Encore merci pour ton aide
saipas est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/07/2009, 01h27   #4
Expert Confirmé
 
Avatar de emmanuel.remy
 
Emmanuel REMY
Inscription : novembre 2005
Messages : 2 826
Détails du profil
Informations personnelles :
Nom : Emmanuel REMY
Âge : 43

Informations forums :
Inscription : novembre 2005
Messages : 2 826
Points : 3 560
Points : 3 560
Re,

Ce n'est pas une "astuce" mais la démarche normale dans le cadre d'un appel asynchrone: tu ne peux pas accéder de suite aux données car ton script ne bloque pas le navigateur le temps de l'appel AJAX. D'où la fonction de rappel

Si tu souhaites faire ce que tu inscris, alors le code ressemblera - de base - à cela:
Code :
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
//fctn est la fonction qui recevra le tableau des lignes récupérées
function fetchSQL(num, arg, fctn)
{
    var xhr=null;
    if (window.XMLHttpRequest) { 
        xhr = new XMLHttpRequest();
    }
    else if (window.ActiveXObject) 
    {
        xhr = new ActiveXObject("Microsoft.XMLHTTP");
    }
 
    xhr.onreadystatechange = function() { 
        if (xhr.readyState==4) 
        {
	        var	docX = xhr.responseXML;
                var ii = [];
	        var items = docX.getElementsByTagName("rep");
	        if (items.length != 0){
		        for (i=0;i<items.length;i++)
		      	{
			      	ii[i] = items[i].getAttribute("ii");
		      	}
                        if (fctn) fctn(ii);
	        }
		    else
		        {alert("rien trouvé");}
        }
    };
    xhr.open("GET", "requete_mysql_xml.php?num=" + num + "&arg=" + arg, true);
    xhr.send(null);
}
Et tu appelles ta fonction ainsi:
Code :
1
2
3
4
5
6
7
8
 
 fetchSQL(num, arg, function(rslt ){
       for (var i=0;i<rslt.length;i++)
  	    {
      	     nv = new Option(rslt[i]);
  	     document.getElementById('selectObj').options[   document.getElementById('selectObj').length ] = nv;
  	}
    });
Et bien sûr si ta fonction fetchSQL n'a pas besoin de ce caractère "générique", alors tu intègres directement le code de la fonction de traitement au sein de fetchSQL.

ERE
__________________
Quand une tête pense seule, elle devient folle.
emmanuel.remy est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/07/2009, 01h48   #5
Invité régulier
 
Inscription : avril 2004
Messages : 61
Détails du profil
Informations forums :
Inscription : avril 2004
Messages : 61
Points : 9
Points : 9
Wow, je t'avouerais que je ne comprends pas tout (voire rien) à ce que tu as fait, mais en tous cas ça marche nickel

Merci pour l'aide!!
saipas est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/07/2009, 02h01   #6
Invité régulier
 
Inscription : avril 2004
Messages : 61
Détails du profil
Informations forums :
Inscription : avril 2004
Messages : 61
Points : 9
Points : 9
Lol, je reviens à l'attaque...
En fait j'utilise pas mal la fonction fetchSQL dans l'api (à chaque fois que je fais une requête vers la base) et j'aurais bien aimé avoir un appel à la fonction du style funct(param). C'est possible?

J'ai essayé de reconstruire un autre tableau à partir de l'autre mais ça fonctionne pas.. je suppose que c'est dû au fait que je ne comprends pas ce que fait ta fonction
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 
//marche pas
function fetchSQL2(num, arg)
{
	var rslt2 = [];
	fetchSQL(num, arg, function(rslt) {
	    for (i=0;i<rslt.length;i++)
	  	{
	      	rslt2[i] = rslt[i];
	  	}
	});
	return rslt2;
}
 
function fillin(num, arg){
	var rslt = fetchSQL2(num, arg);
    for (i=0;i<rslt.length;i++)
  	{
      	nv = new Option(rslt[i]);
      	document.getElementById('selectObj').options[document.getElementById('selectObj').length] = nv;
  	}
}
saipas est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/07/2009, 02h10   #7
Expert Confirmé
 
Avatar de emmanuel.remy
 
Emmanuel REMY
Inscription : novembre 2005
Messages : 2 826
Détails du profil
Informations personnelles :
Nom : Emmanuel REMY
Âge : 43

Informations forums :
Inscription : novembre 2005
Messages : 2 826
Points : 3 560
Points : 3 560
Non, c'est toujours le même souci, le fait que la requête AJAX est asynchrone. Tu ne peux donc pas faire:
Code :
1
2
3
4
5
6
7
8
	var rslt2 = [];
	fetchSQL(num, arg, function(rslt) {
	    for (i=0;i<rslt.length;i++)
	  	{
	      	rslt2[i] = rslt[i];
	  	}
	});
	return rslt2;
Sur le principe c'est ok, sauf que le return a lieu alors que la requete AJAX n'est pas finie...

Et cela ne t'apporte pas grand chose... plutôt faire:
Code :
1
2
3
4
5
6
7
8
9
function fillin(num, arg){
	fetchSQL(num, arg, function(rslt) {
           for (i=0;i<rslt.length;i++)
  	      {
      	      nv = new Option(rslt[i]);
      document.getElementById('selectObj').options[document.getElementById('selectObj').length] = nv;
  	      }
       }
}
Je ne suis pas convaincu de l'intérêt (ou de l'avantage) de créer une telle focntion mais c'est la démarche.

ERE
__________________
Quand une tête pense seule, elle devient folle.
emmanuel.remy est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/07/2009, 02h17   #8
Invité régulier
 
Inscription : avril 2004
Messages : 61
Détails du profil
Informations forums :
Inscription : avril 2004
Messages : 61
Points : 9
Points : 9
Ok merci pour la réponse.

Je fais ça parce qu'à côté j'ai un appel à la fonction fillin depuis un bouton. Là en l'occurence c'est une page test donc effectivement c'est pas folichon mais sur mes autres pages ça va chercher des valeurs de textbox puis fait une recherche dans la base.

Voili voilou, merci encore
saipas est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/07/2009, 02h24   #9
Expert Confirmé
 
Avatar de emmanuel.remy
 
Emmanuel REMY
Inscription : novembre 2005
Messages : 2 826
Détails du profil
Informations personnelles :
Nom : Emmanuel REMY
Âge : 43

Informations forums :
Inscription : novembre 2005
Messages : 2 826
Points : 3 560
Points : 3 560
Citation:
Envoyé par saipas Voir le message
Ok merci pour la réponse.

Je fais ça parce qu'à côté j'ai un appel à la fonction fillin depuis un bouton. Là en l'occurence c'est une page test donc effectivement c'est pas folichon mais sur mes autres pages ça va chercher des valeurs de textbox puis fait une recherche dans la base.

Voili voilou, merci encore
OK, je comprends un peu mieux, ce sera effectivement plus clair ainsi

Bon dev,

ERE
__________________
Quand une tête pense seule, elle devient folle.
emmanuel.remy est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/07/2009, 02h51   #10
Invité régulier
 
Inscription : avril 2004
Messages : 61
Détails du profil
Informations forums :
Inscription : avril 2004
Messages : 61
Points : 9
Points : 9
Petite précision : j'ai dû modifier ça dans la fonction fetchSQL, sinon quand il n'y avait pas de résultat à la requête ça ne renvoyait rien du tout...
Code :
1
2
3
4
5
6
 
		    else
		    {
		        ii[0] = "Rien trouvé";
		        fctn(ii);
		    }
A+
saipas est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/07/2009, 03h05   #11
Expert Confirmé
 
Avatar de emmanuel.remy
 
Emmanuel REMY
Inscription : novembre 2005
Messages : 2 826
Détails du profil
Informations personnelles :
Nom : Emmanuel REMY
Âge : 43

Informations forums :
Inscription : novembre 2005
Messages : 2 826
Points : 3 560
Points : 3 560
Plutôt:
Code :
1
2
3
4
5
6
7
8
9
 
var ii = [ "Rien trouvé" ];
if (items.length > 0){
  for (i=0;i<items.length;i++)
  {
     ii[i] = items[i].getAttribute("ii");
  }
}
fctn(ii);


ERE
__________________
Quand une tête pense seule, elle devient folle.
emmanuel.remy est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/07/2009, 03h26   #12
Invité régulier
 
Inscription : avril 2004
Messages : 61
Détails du profil
Informations forums :
Inscription : avril 2004
Messages : 61
Points : 9
Points : 9
Adjugé vendu!
saipas est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +1. Il est actuellement 05h59.


 
 
 
 
Partenaires

Hébergement Web