Précédent   Forum des professionnels en informatique > Webmasters - Développement Web > JavaScript
JavaScript Forum programmation JavaScript. Lire Cours JavaScript, 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
Nouveau membre du Club
 
Date d'inscription: avril 2004
Messages: 59
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 :
 
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
Vieux 06/07/2009, 00h22   #2
Rédacteur/Modérateur
 
Avatar de emmanuel.remy
 
Nom : Emmanuel REMY
Date d'inscription: novembre 2005
Localisation: Grand Perron des Encombres
Âge: 41
Messages: 2 466
Par défaut

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 :
 
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
Vieux 06/07/2009, 00h36   #3
Nouveau membre du Club
 
Date d'inscription: avril 2004
Messages: 59
Par défaut

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 :
 
	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
Vieux 06/07/2009, 01h27   #4
Rédacteur/Modérateur
 
Avatar de emmanuel.remy
 
Nom : Emmanuel REMY
Date d'inscription: novembre 2005
Localisation: Grand Perron des Encombres
Âge: 41
Messages: 2 466
Par défaut

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 :
//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 :
 
 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
Vieux 06/07/2009, 01h48   #5
Nouveau membre du Club
 
Date d'inscription: avril 2004
Messages: 59
Par défaut

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
Vieux 06/07/2009, 02h01   #6
Nouveau membre du Club
 
Date d'inscription: avril 2004
Messages: 59
Par défaut

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 :
 
//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
Vieux 06/07/2009, 02h10   #7
Rédacteur/Modérateur
 
Avatar de emmanuel.remy
 
Nom : Emmanuel REMY
Date d'inscription: novembre 2005
Localisation: Grand Perron des Encombres
Âge: 41
Messages: 2 466
Par défaut

Non, c'est toujours le même souci, le fait que la requête AJAX est asynchrone. Tu ne peux donc pas faire:
Code :
	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 :
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
Vieux 06/07/2009, 02h17   #8
Nouveau membre du Club
 
Date d'inscription: avril 2004
Messages: 59
Par défaut

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
Vieux 06/07/2009, 02h24   #9
Rédacteur/Modérateur
 
Avatar de emmanuel.remy
 
Nom : Emmanuel REMY
Date d'inscription: novembre 2005
Localisation: Grand Perron des Encombres
Âge: 41
Messages: 2 466
Par défaut

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
Vieux 06/07/2009, 02h51   #10
Nouveau membre du Club
 
Date d'inscription: avril 2004
Messages: 59
Par défaut

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 :
 
		    else
		    {
		        ii[0] = "Rien trouvé";
		        fctn(ii);
		    }
 
A+
saipas est déconnecté   Envoyer un message privé Réponse avec citation
Vieux 06/07/2009, 03h05   #11
Rédacteur/Modérateur
 
Avatar de emmanuel.remy
 
Nom : Emmanuel REMY
Date d'inscription: novembre 2005
Localisation: Grand Perron des Encombres
Âge: 41
Messages: 2 466
Par défaut

Plutôt:
Code :
 
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
Vieux 06/07/2009, 03h26   #12
Nouveau membre du Club
 
Date d'inscription: avril 2004
Messages: 59
Par défaut

Adjugé vendu!
saipas est déconnecté   Envoyer un message privé Réponse avec citation
NEWS JAVASCRIPTF.A.Q JSTUTORIELS JSSOURCES JSLIVRES JS

Réponse Proposer ce sujet en actualité

Précédent   Forum des professionnels en informatique > Webmasters - Développement Web > JavaScript



Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are non
Pingbacks are non
Refbacks are non



Fuseau horaire GMT +1. Il est actuellement 08h08.


Vos questions techniques : forum d'entraide JavaScript - Publiez vos articles, tutoriels et cours
et rejoignez-nous dans l'équipe de rédaction du club d'entraide des développeurs francophones
Nous contacter - Hébergement - Participez - Copyright © 2000-2010 www.developpez.com - Legal informations.