IPB

Bienvenue invité ( Connexion | Inscription )

 
Reply to this topicStart new topic
> fusion de résultats avec deux fonctions $.ajax, problème d'asynchronicité
Options
toluol
posté 26 Feb 2016, 01:41
Message #1


Macbidouilleur d'argent !
***

Groupe : Membres
Messages : 792
Inscrit : 14 Nov 2003
Lieu : Genève
Membre no 11 656



Bonjour,

basiquement, je cherche à fusionner les résultats de deux requêtes $.ajax : Imaginez avoir deux fichiers xml distincts servant à créer un menu (menu1.xml et menu2.xml) où menu2.xml complète menu1.xml et ajoute une hiérarchie dans un noeud précis de menu1.xml... Evidemment, tout cela doit être étudié en fonctions récursives pour avoir un niveau infini de noeud... (Oui, je sais... j'aime bien me compliquer la vie... laugh.gif)

Pour le moment, cela fonctionne récursivement pour le premier fichier xml :

Code
function makeMenu(xml,level){
    var html='<ul>';
    $(xml).find('menu').find('m'+level).each(function(){
        if($(this).children().length){
            html+='<li>'+$(this).attr("title");
                html+=makeMenu(xml,level+1);
            html+='</li>';
        }
        else html+= '<li>'+$(this).attr("title")+'</li>';
        
    });
    html+='</ul>';
    return html;
}

$(document).ready(function(){
    $.ajax({
        type: "GET",
        url: "menu1.xml",
        dataType: "xml",
        success: function(xml){
            $("#menu_wrapper").append(makeMenu(xml,1));
        }
    });
});


menu1.xml est de la forme :
Code
<Site>
    <menu>
        <m1 title="title 1"></m1>
        <m1 title="title 2">
            <m2 title="title 2.1"></m2>
            <m2 title="title 2.2">
                <m3 title="title 2.2.1"></m3>
                <m3 title="title 2.2.2"></m3>
            </m2>
            <m2 title="title 2.3" include="menuInclude2"></m2>
        </m1>
        <m1 title="title 3"></m1>
    </menu>
</Site>
Remarquez l'attribut include="menuInclude2" que je souhaiterais utiliser pour cibler et inclure une nouvelle hiérarchie de menu avec menu2.xml... (en relançant ma fonction "makeMenu" si l'attribut include existe)

menu2.xml est de la même forme :
Code
<Site>
    <menuInclude2>
        <m1 title="menu spécial 1"></m1>
        <m1 title="menu spécial 2">
            <m2 title="menu spécial  2.1"></m2>
            <m2 title="menu spécial  2.2"></m2>
        </m1>
    </menuInclude2>
</Site>




Mon problème, c'est que j'ai toujours traité les données issues de la fonction $.ajax au sein de l'instruction "success", mais il semblerait qu'on pourrait faire un simple return $.ajax comme expliqué ici. Je n'ai hélas jamais réussi à faire marcher mon code avec leurs exemples ! sad.gif

Merci d'avance pour votre aide.

Ce message a été modifié par toluol - 26 Feb 2016, 01:56.
Go to the top of the page
 
+Quote Post
No6
posté 26 Feb 2016, 16:24
Message #2


Oui ?
*****

Groupe : Membres
Messages : 3 889
Inscrit : 24 Jun 2003
Lieu : BZH
Membre no 8 224



c'est important que tes données soient en xml ??
==> en Javascript, on fini toujours par manipuler du json... (et c'est plus simple à relire.

dans ton exemple (stackoverflow) il est aussi question d'un appel ajax sur un script php inconnu.

il existe une fonction jQuery toute simple pour lire un fichier json : jQuery.getJSON() => http://api.jquery.com/jquery.getjson/

et pour inserer un élément json sur un noeud, cela ne represente qu'un affectation.

et parcourir un arbre json c'est bien plus simple que de parser du xml...


bref, pourquoi faire simple quand on peut faire compliqué ??? cool.gif


--------------------
"Je sais que vous croyez comprendre ce que vous pensez que j'ai dit, mais je ne suis pas sûr que vous réalisiez que ce que vous avez entendu n'est pas ce que je pense."
(Alan Greenspan)
Go to the top of the page
 
+Quote Post
toluol
posté 26 Feb 2016, 17:39
Message #3


Macbidouilleur d'argent !
***

Groupe : Membres
Messages : 792
Inscrit : 14 Nov 2003
Lieu : Genève
Membre no 11 656



Oui, cela peut paraître plus compliqué comme ça, mais pas vraiment au sein de l'environnement que j'ai déjà mis en place... puisque j'ai déjà un "générateur" php pour créer mes xml à partir de mes bases sql. Le xml est évidemment simple à parcourir en php avec simpleXML et le json avec jquery, mais de toute manière... j'ai du "travail" à faire, non ?

Mon but étant de pouvoir basculer très facilement (en un clic si je veux) d'une navigation php (avec variable de session) à une navigation ajax avec jquery (avec les variables js) à partir d'une même structure (base de donnée+xml) (En ligne de mire: phonegap *)

De plus j'aurai des "parties" de menu (comme expliqué au début du post, car certaines resteront statiques et d'autre seront "dynamiques", générées à la volée... enfin bref...! ^^) S'il faut que je fasse cela à double dans les deux systèmes (xml et json), pas sûr que j'y gagne au final !?

Citation (No6 @ 26 Feb 2016, 16:24) *
dans ton exemple (stackoverflow) il est aussi question d'un appel ajax sur un script php inconnu.


Oui, c'est vrai... c'est un script php qui retourne un résultat et non le chargement d'un fichier xml qui doit encore être traité au travers d'une fonction de parsing du xml en js...

* EDIT : + Apache Cordova

Ce message a été modifié par toluol - 26 Feb 2016, 18:11.
Go to the top of the page
 
+Quote Post
No6
posté 26 Feb 2016, 18:26
Message #4


Oui ?
*****

Groupe : Membres
Messages : 3 889
Inscrit : 24 Jun 2003
Lieu : BZH
Membre no 8 224



Citation
Oui, c'est vrai... c'est un script php qui retourne un résultat et non le chargement d'un fichier xml qui doit encore être traité au travers d'une fonction de parsing du xml en js...

donc le résultat du script php recupere un résultat depuis une requete SQL avec laquelle il fabrique un résultat en xml pour l'envoyer via du ajax à un script en js qui doit parser

et comme le format des variables en javascrit correspond à le norme json, le sccritp js transforme à son tour le xml en json (var xyz = 15; => c'est déjà une syntaxe json)

partie php
Code
<?php
mb_internal_encoding("UTF-8");

$arg_0    = (isSet($_POST['arg0']))    ? $_POST['arg0']    : "marignan";        
$arg_1    = (isSet($_POST['arg1']))    ? $_POST['arg1']    : 1515;

$menu[0] = "menu spécial 1";
$menu[1] = array("menu spécial 2", array ("menu spécial  2.1", "menu spécial  2.2");

header('Content-type: application/json');
echo json_encode($menu);
exit(0);
?>


partie js
Code
var
    Call_Args = {
    arg1    : "Vase de Soissons",
    arg2    : 486;
};

$.ajax({
    url    : "rep/fic.php",
    type    : 'POST',
    data     : Call_Args,
    cache     : false,
    dataType  : 'json',
    error     : function(request, error) { alert("Erreur : responseText: "+request.responseText); },
    success     : function(data) {
     // les variables de retour sont dans => data[x][y],
    }
});  // ajax


Ps: pour connaitre le nombre d'éléments à un niveau

nbelems = Object.keys(data).length;
nbelem1 = Object.keys(data[0]).length; // et ainsi de suite


Ce message a été modifié par baron - 28 Feb 2016, 03:15.


--------------------
"Je sais que vous croyez comprendre ce que vous pensez que j'ai dit, mais je ne suis pas sûr que vous réalisiez que ce que vous avez entendu n'est pas ce que je pense."
(Alan Greenspan)
Go to the top of the page
 
+Quote Post
toluol
posté 27 Feb 2016, 00:45
Message #5


Macbidouilleur d'argent !
***

Groupe : Membres
Messages : 792
Inscrit : 14 Nov 2003
Lieu : Genève
Membre no 11 656



A ce moment là, pourquoi créer un script php supplémentaire "juste" pour la fonction ajax et retournant du json qui devra à son tour être recompilé en html ?
Autant sortir de l'html directement, non ?

A la lecture des pages web :
un fichier php indépendant parse plusieurs fichier xml et retourne des menus html "prêt à l'emploi"
=> ...et soit ce fichier est directement inclut en php
=> ...soit il est retourné en ajax

Ah... hum... ouais... euh...!!! peut-être que cela pose problème en fonction du nombre de profondeurs et de l'endroit où distribuer ces menus... et là json, pourrait être d'un grand secours ? Pfiu... cela devient abstrait tant que je n'ai pas essayé !

De plus, je n'ai pas été clair dans mes explications précédentes... désolé. (C'est que ce n'est pas si simple)

En gros, il y a trois niveaux d'intervenants : Un super utilisateur qui "crée" tout le site (via un super CMS), des administrateurs qui modifient le contenu du site (via un CMS), et des utilisateurs-internautes qui utilisent le site. Mon idée était d'avoir deux parties dans la base de données : Une qui permet la création du site (pour le super utilisateur), générant des pages html, du css, du xml, du php... bref, un peu de tout, mais qui, une fois le site créé peut être désinstallée du domaine sans affecter la bonne marche du site. La deuxième partie de la base (pour les administrateurs) prend ensuite le relais pour l'ajout/suppression/modification de données plus légères (mais pouvant affecter quelques menus quand même)

Et concernant l'ajax sur les menus, c'est dans le but (euh l'espoir ?), si besoin, de sortir de ces pages html/css/js une application mobile simple mais native à l'aide de Phonegap ou Cordova... Mais j'ai encore sacrément besoin de m'y plonger... je sais ! J'ai cru comprendre que le php était utilisable, mais uniquement au travers de fonctions ajax (ce que je ne comprends pas bien, mais bon... voilà pourquoi, je me creuse autant les neurones et semblent faire les choses de façon compliquées !

Je crois que je vais d'abord étudier cela de plus près... tongue.gif

Ce message a été modifié par toluol - 27 Feb 2016, 00:55.
Go to the top of the page
 
+Quote Post
No6
posté 27 Feb 2016, 01:52
Message #6


Oui ?
*****

Groupe : Membres
Messages : 3 889
Inscrit : 24 Jun 2003
Lieu : BZH
Membre no 8 224



Citation (toluol @ 27 Feb 2016, 00:45) *
A ce moment là, pourquoi créer un script php supplémentaire "juste" pour la fonction ajax et retournant du json qui devra à son tour être recompilé en html ?
Autant sortir de l'html directement, non ?


c''est la solution la plus simple !

$('#MonMenu').load('rep/fabrikmenu.php');

la seule utilité de passer par un traitement d'un retour des valeurs est si tu veux prélever des valeurs internes qui ne sont pas utiles au menu.

sinon il y aussi l'attribut data en html qui peut y servir.



--------------------
"Je sais que vous croyez comprendre ce que vous pensez que j'ai dit, mais je ne suis pas sûr que vous réalisiez que ce que vous avez entendu n'est pas ce que je pense."
(Alan Greenspan)
Go to the top of the page
 
+Quote Post
No6
posté 27 Feb 2016, 02:08
Message #7


Oui ?
*****

Groupe : Membres
Messages : 3 889
Inscrit : 24 Jun 2003
Lieu : BZH
Membre no 8 224



Citation (toluol @ 27 Feb 2016, 00:45) *
Et concernant l'ajax sur les menus, c'est dans le but (euh l'espoir ?), si besoin, de sortir de ces pages html/css/js une application mobile simple mais native à l'aide de Phonegap ou Cordova... Mais j'ai encore sacrément besoin de m'y plonger... je sais ! J'ai cru comprendre que le php était utilisable, mais uniquement au travers de fonctions ajax (ce que je ne comprends pas bien, mais bon... voilà pourquoi, je me creuse autant les neurones et semblent faire les choses de façon compliquées !


d'apres ce que j'ai lu sur Cordova (ancienement nommé PhoneGap) on est quasiment dans une configuration de site one page.
de base on à uniquement le droit d'utiliser html/css/js et rien d'autre.
le seul moyen de capter(ou d'envoyer des données) des données, comme par exemple sur un sgbd / mail / ... , c'est de passer par ajax.

Ce message a été modifié par No6 - 27 Feb 2016, 02:10.


--------------------
"Je sais que vous croyez comprendre ce que vous pensez que j'ai dit, mais je ne suis pas sûr que vous réalisiez que ce que vous avez entendu n'est pas ce que je pense."
(Alan Greenspan)
Go to the top of the page
 
+Quote Post
Jaypee
posté 27 Feb 2016, 07:33
Message #8


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 486
Inscrit : 29 Aug 2002
Membre no 3 340



JQuery a une API parseXML qui permet ensuite de faire des find, lire les attributs etc...

Exemple de code : http://stackoverflow.com/questions/1846594...uery-javascript

Conseil pour la récursivité:
Essayer d'écrire les fonctions "tail récursive", qu'on peut facilement transformer en itération par la suite:
function ajouteMenu(menu_in, menu_out) {
...
}
lorsque menu_in est vide, on retourne menu_out qui bien sûr est vide au départ. L'appel récursif est isolé, il ne se compose pas avec une opération en attente sur la pile. D'où un risque diminué de faire un "stack overflow"

Dans cette approche la factorielle s'écrirait
fonction fact(n, res) {
si (n == 0) {
res
} sinon {
fact( n - 1, n * res)
}
}
Pour le plaisir des yeux, on peut ensuite l'emballer dans une fonction plus classique:
fonction factorielle(n) {
fact(n, 1)
}
J-P

Ce message a été modifié par Jaypee - 27 Feb 2016, 07:38.
Go to the top of the page
 
+Quote Post
toluol
posté 27 Feb 2016, 09:58
Message #9


Macbidouilleur d'argent !
***

Groupe : Membres
Messages : 792
Inscrit : 14 Nov 2003
Lieu : Genève
Membre no 11 656



[Ok... Merci pour vos commentaires ! Cela m'aide bien dans ma réflexion !

Citation (No6 @ 27 Feb 2016, 02:08) *
d'apres ce que j'ai lu sur Cordova (ancienement nommé PhoneGap) on est quasiment dans une configuration de site one page.
de base on à uniquement le droit d'utiliser html/css/js et rien d'autre.
le seul moyen de capter(ou d'envoyer des données) des données, comme par exemple sur un sgbd / mail / ... , c'est de passer par ajax.


Oui, c'est bien ça ! Mais bon, selon comme on organise l'affichage avec le CSS et le javascript, j'imagine qu'on arrive à créer l'illusion de quelque chose de plus complexe, et avec ajax, remplir la structure selon nos besoins... Après, est-ce que le CSS (Jusqu'au CSS3) et jquery sont toujours bien traduits par Cordova, je suis dans l'ignorance !
Je vais creuser le sujet !

Citation (Jaypee @ 27 Feb 2016, 07:33) *
Conseil pour la récursivité:
Essayer d'écrire les fonctions "tail récursive", qu'on peut facilement transformer en itération par la suite:
function ajouteMenu(menu_in, menu_out) {
...
}
lorsque menu_in est vide, on retourne menu_out qui bien sûr est vide au départ. L'appel récursif est isolé, il ne se compose pas avec une opération en attente sur la pile. D'où un risque diminué de faire un "stack overflow"


Je vois l'idée du "menu_in/menu_out" avec un test si vide pour continuer l'itération, mais cela revient au même (ou presque) que mon instruction "if($(this).children().length){" comme test sur chaque "noeud" pour éviter tout "stack overflow"... Et si je dois entourer les résultats de <ul><li></li></ul> selon les niveaux de profondeur, il me paraît impossible de transformer ma fonction selon ton idée... ou bien ? Comment t'y prendrais-tu pour gérer l'imbrication des balises <ul> et <li> ?

Code
function makeMenu(xml,level){
    var html='<ul>';
    $(xml).find('menu').find('m'+level).each(function(){
        if($(this).children().length){
            html+='<li>'+$(this).attr("title");
                html+=makeMenu(xml,level+1);
            html+='</li>';
        }
        else html+= '<li>'+$(this).attr("title")+'</li>';
        
    });
    html+='</ul>';
    return html;
}
Go to the top of the page
 
+Quote Post
Jaypee
posté 27 Feb 2016, 22:34
Message #10


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 486
Inscrit : 29 Aug 2002
Membre no 3 340



La grosse différence tient dans la ligne:
html += MakeMenu(xml, level + 1);
qui reste en attente de la fin de l'appel récursif. Sur la pile à chaque appel récursif une opération supplémentaire est en attente.

Ce qui est équivalent à fact(n) = n * fact(n -1), plus n est grand plus la pile augmente.

J-P
Go to the top of the page
 
+Quote Post
toluol
posté 28 Feb 2016, 12:37
Message #11


Macbidouilleur d'argent !
***

Groupe : Membres
Messages : 792
Inscrit : 14 Nov 2003
Lieu : Genève
Membre no 11 656



Ah je viens de comprendre ..... ! Il faut donc transmettre le résultat à chaque fois dans la fonction pour éviter html+= mafonction
donc, dans mon cas, plutôt quelque chose comme ça : makeMenu(xml,level,html); ?

...seulement... lorsqu'on parcourt une hiérarchie xml et qu'on doit entourer tout ça de <li> et de <ul>, c'est un peu plus complexe qu'une factorielle qui a un unique résultat à chaque passage de fonction ! sad.gif Faut-il passer par plusieurs fonctions ? utiliser des variables tableaux ? utiliser "plusieurs piles" avec plusieurs stockage d'html ?
...Je crois que j'ai besoin d'aide...

M'étant remis à du php classique, voici ma requête récursive actuelle :
Code
if(file_exists('menu.xml')){$xml=simplexml_load_file('menu.xml');}
else{echo'echec chargement.';exit();}

function makeMenu($xml,$level=0) {
    $html='<ul>';
    $arr=$xml->children();
    if(sizeof($arr)>0){
        foreach($arr as $child) {
            $html.= '<li>'.$child[0]['title'];
            if(sizeof($child->children())>0){
                $html.= makeMenu($child,$level+1);
            }
            $html.= '</li>';
        }
    }
    else{
        $html.= '<li>'.$arr[0]['title'].'</li>';
    }
  $html.= '</ul>';
  return $html;
}

echo makeMenu($xml->menu);


et mon xml, toujours de la forme :
Code
<xml>
    <menu>
        <m title="title 1"></m>
        <m title="title 2">
            <m title="title 2.1"></m>
            <m title="title 2.2">
                <m title="title 2.2.1"></m>
                <m title="title 2.2.2"></m>
            </m>
            <m title="title 2.3"></m>
        </m>
        <m title="title 3"></m>
    </menu>
</xml>


Ce message a été modifié par toluol - 28 Feb 2016, 13:15.
Go to the top of the page
 
+Quote Post
Jaypee
posté 28 Feb 2016, 14:24
Message #12


Macbidouilleur d'Or !
*****

Groupe : Membres
Messages : 2 486
Inscrit : 29 Aug 2002
Membre no 3 340



Il y a peut-être une tout autre approche possible avec du XSLT:

http://stackoverflow.com/questions/4703312...an-xml-xsl-file

Cependant, il faut un "moteur" xslt en JS, qui existe. http://johannburkard.de/blog/programming/j...ery-plugin.html ou en PHP: http://bob.developpez.com/phpxslt/

J-P
Go to the top of the page
 
+Quote Post
toluol
posté 28 Feb 2016, 14:49
Message #13


Macbidouilleur d'argent !
***

Groupe : Membres
Messages : 792
Inscrit : 14 Nov 2003
Lieu : Genève
Membre no 11 656



hum... mais honnêtement... ces problèmes de pile peuvent être réellement problématique à partir de quel niveau ?
...Si on a un menu d'une cinquantaine de nœud, ou allez... voir jusqu'à 300 nœuds (je n'imagine jamais aller au delà...!), cela pose déjà un problème ?
...pour des petites configurations comme des appareils mobiles par exemple ? ...ou est-ce toujours problématique ?

Go to the top of the page
 
+Quote Post
No6
posté 29 Feb 2016, 00:42
Message #14


Oui ?
*****

Groupe : Membres
Messages : 3 889
Inscrit : 24 Jun 2003
Lieu : BZH
Membre no 8 224



Citation (Jaypee @ 28 Feb 2016, 14:24) *
Il y a peut-être une tout autre approche possible avec du XSLT:

http://stackoverflow.com/questions/4703312...an-xml-xsl-file

Cependant, il faut un "moteur" xslt en JS, qui existe. http://johannburkard.de/blog/programming/j...ery-plugin.html ou en PHP: http://bob.developpez.com/phpxslt/

J-P

Marrant tongue.gif
Ca fait un moment que j'ai rien codé en xslt, à l'époque c'était pour produire des fichiers pdf (avec du xsl-fo en plus)

J'aimais bien, et c'est sympa de voir qu'il existe des solutions en javascript ou en PHP smile.gif

Mais pour ce qui est de Cordova, je suis pas certain que ce soit le meilleur moyen d'atteindre le nirvana.
et tout ce résumera entre les compromis sur les temps de calcul sur mobile (en JS) et ceux des Appels Ajax avec des prétraitements PHP, pour obtenir la meilleure fluidité dans l'expérience utilisateurs...

Cordova c'est un petit monde en soi, et il vaut mieux bien le maitriser sans trop de fioritures pour commencer.

Apres on peut étoffer avec jQuery et jQuery-mobile pour continuer...


--------------------
"Je sais que vous croyez comprendre ce que vous pensez que j'ai dit, mais je ne suis pas sûr que vous réalisiez que ce que vous avez entendu n'est pas ce que je pense."
(Alan Greenspan)
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 utilisateur(s) sur ce sujet (1 invité(s) et 0 utilisateur(s) anonyme(s))
0 membre(s) :

 



Nous sommes le : 28th March 2024 - 22:29