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 :

[DOM] Fonctions "imbriquées" et valeur de retour


Sujet :

JavaScript

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    201
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 201
    Points : 108
    Points
    108
    Par défaut [DOM] Fonctions "imbriquées" et valeur de retour
    Salut,

    J'utilise plusieurs fonctions dans une fonction principale, principalement pour gérer des effets, attendre des réponses AJAX, etc...
    Le problème étant que tout le traitement se fait à travers l'ensemble de ces fonctions. Par conséquent, la valeur de retour de la fonction principale en dépend.

    Ce que je voudrais c'est "synchroniser" la valeur de retour après l'appel de chaque fonction nécessaire à sa définition.

    Si quelqu'un a une idée de comment faire ce genre de choses...

  2. #2
    Rédacteur
    Avatar de marcha
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2003
    Messages
    1 571
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 571
    Points : 2 351
    Points
    2 351
    Par défaut
    Salut,

    Un petit bout de code pour illustrer ?

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    201
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 201
    Points : 108
    Points
    108
    Par défaut
    Biensûr

    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
    // Il s'agit d'une gestion de rubriques à travers un composant 'arbre'
    // Le tout geré en drag and drop:
    tree.enableDragAndDrop(1);
    tree.setDragHandler(treeDrop); // Fonction pour laquelle je veux une valeur de retour bien précise
    
    // La fonction elle même:
    function treeDrop(srcID, dstID) {
    		
    	state_span.innerHTML = 'Déplacement de la catégorie...';
    		
    	Effect.Appear(state_div, {
    		duration: 1,
    		afterFinish: function () {
    			new Ajax.Request('AJAX/PHP/categories.move.php', {
    				method: 'POST',
    				parameters: {src_id: srcID, dest_id: dstID},
    				
    				onSuccess: function(transport) {
    					Effect.Fade(state_div, {
    						duration: 1,
    						afterFinish: function () {
    							json = eval(transport.getResponseHeader('X-JSON'));
    							
    							if (typeof(json.error) != 'undefined') {
    								widget_show_error(json.error);
    								tree.moveItem(srcID, dstID);
    								// Ici j'aimerais renvoyer false
    							}
    							else {
    								widget_remove_errors();
    								// Ici j'aimerais renvoyer true
    							}
    						}
    					});
    				}
    			});
    		}
    	});
    	return true;
    }

  4. #4
    Rédacteur
    Avatar de marcha
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2003
    Messages
    1 571
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 571
    Points : 2 351
    Points
    2 351
    Par défaut
    Salut,

    Ta fonction principale va se terminer bien avant même que les autres ne
    sont appellées. Par exemple, la fonction anonyme du onSuccess
    de la requête sera appellée lorsque le serveur aura daigné répondre.

    Ta fonction principale sera terminée et il est trop tard pour qu'elle retourne
    qqch. Je crois que si tu implémente un mécanisme d'attente tu risque de
    bloquer ton interface utilisateur durant l'attente.

    Je pense qu'il te faut appeler une callback lorsque t'on traitement est terminé.

    Si je t'ai bien compris tu envisages ton code ainsi:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    function evenement_utilisateur() {
      if(treeDrop(...)) {
         //... faire qqch quand c'est ok
      } else {
         //... faire qqch quand c'est pas ok
      }
    }
    Je pense qu'il faut le penser ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    function toutestok() {
       //... faire qqch quand c'est ok
    }
    function pasok() {
       //... faire qqch quand c'est pas ok
    }
    function evenement_utilisateur() {
       treeDrop(..., pasok, toutestok);
    }
    pasok et toutestok sont des références à des fonctions callback que tu
    appelles là où tu pensais mettre ton return true, ou return false

    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
     
    // La fonction elle même:
    function treeDrop(srcID, dstID, ok_callback, pasok_callback) {
     
    ...
    if (typeof(json.error) != 'undefined') {
        widget_show_error(json.error);
        tree.moveItem(srcID, dstID);
        // Ici j'aimerais renvoyer false
        pasok_callback();
    }
    else {
    	widget_remove_errors();
    	// Ici j'aimerais renvoyer true
        ok_callback();
    }
    quand tu appelles treeDrop tu peux aussi utiliser des fonctions anonymes
    pour gérer la réussite et l'échec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    treeDrop(..., function() { /* ok */ }, function() { /* pas ok */ } );
    en espérant avoir bien compris ta question :-)

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    201
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 201
    Points : 108
    Points
    108
    Par défaut
    Tout d'abord merci beaucoup pour cette réponse très bien détaillée marcha.

    J'ai essayé de suivre ton raisonnement, tu as très bien cerné le problème, par contre je ne pense pas que la solution fonctionne.

    Je m'explique:

    treeDrop est elle même une fonction de callback. Sa valeur de retour va déterminer l'action à appliquer après son appel.
    Si je fais comme tu viens de l'expliquer, le problème restera le même, la valeur de retour sera envoyée avant le traitement de la requête et même en appelant une fonction de callback, il sera trop tard.
    Il faudrait que je puisse mettre en attente la fonction jusqu'à la fin du traitement.. Mais je ne vois absolument pas comment faire ça.

    Peut-être créer un évènement, qu'en penses-tu ?

  6. #6
    Rédacteur
    Avatar de marcha
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2003
    Messages
    1 571
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 571
    Points : 2 351
    Points
    2 351
    Par défaut
    Ok :-) sorry j'avais pas fait attention.

    Est-ce que tu peux me dire l'objet tree que tu utilises ?
    J'ai trouvé ceci http://www.scbr.com/docs/products/dh...ee/index.shtml
    c'est celui là ?

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    201
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 201
    Points : 108
    Points
    108
    Par défaut
    Oui c'est bien ça !

    Dans sa version standard biensûr, c'est pour ça que je galère d'ailleurs..

    PS: Je suis en train de regarder avec une fonction qui boucle par un setTimeout, j'ai obtenu quelques résultats mais rien de très propre / satisfaisant..

    Merci de te pencher sur mon problème ;)

  8. #8
    Rédacteur
    Avatar de marcha
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2003
    Messages
    1 571
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Suisse

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 571
    Points : 2 351
    Points
    2 351
    Par défaut
    Salut,

    J'ai le sentiment que cet objet Tree est architecturé pour travailler
    avec des requêtes ajax synchrones. Regarde la fonction doOnBeforeDrop(...)
    de l'exemple donné pour la synchro avec une db sur le serveur.

    http://www.scbr.com/docs/products/dh..._db_sample.zip

    En particulier à la ligne 129
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    var dropSaver = new dtmlXMLLoaderObject(null,null,false);//sync mode
    De ce fait je vois mal comment tu pourrais faire autrement que de travailler
    avec une requête synchrone toi aussi.

    Tu as deux problèmes à résoudre

    1) La librairie prototype propose un mode synchrone dans Ajax.Request,
    mais il me semble qu'il effectue quand même un appel à une callback une
    fois la requête terminée. Ce qui ne t'arrange pas dans ton cas.

    2) Pendant la requête synchrone le script est "bloqué" en l'attente de la
    réponse, ce qui va poser problème avec tes effets de fade.

    Voici un exemple de code simple qui illustre ce problème, j'en ai profité
    pour accéder directement à XmlHttpRequest pour éviter le problème #1
    lié à la callback. Pour faire fonctionner cet exemple, crée une page coté
    serveur qui dort 3 secondes.

    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
     
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title>Page Title</title>
    <script type="text/javascript" src='prototype.js'></script>
    <script type="text/javascript">
     
    function effet() {
    	$('container').innerHTML++;
    	setTimeout(effet, 100);
    }
     
    function drop() {
    	var xhr=Ajax.getTransport();
    	xhr.open("GET","/wait.php",false);
    	xhr.send(null);
        alert('ok');
    }
     
    function init() {
    	effet();
    	Event.observe($('button'), 'click', drop);
    }
     
    Event.observe(window, 'load', init);
     
    </script>
     
    </head><body>
     
    <div id='container'>0</div>
    <div id='button'>click</div>
     
    </body></html>
    Il y a un compteur qui tourne rapidement avec un setTimeout pour illustrer
    un Effet. Quand tu click ça fait une requête synchrone qui interrompt le compteur.

    Suite à ce petit test, je pense que tu peux trouver un compromis pour ton
    application en procédant ainsi:

    tu commences par faire la requête synchrone dans treeDrop, cela bloque
    l'interface un petit moment (le temps de la requête). Ensuite tu détermine
    si il y a echec et tu return false. Sinon tu lances les effets puis tu return true.

    Les effets se produiront apres que ton objet Tree aura reçu le "true", il faut
    voir si il n'y aura pas un conflit entre les effets et les éventuelles manipulations
    du DOM faite par l'objet Tree ?

    Si qqn a une meilleure idée ça m'intéresse.

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    201
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 201
    Points : 108
    Points
    108
    Par défaut
    Salut marcha,

    Ta solution est intéressante mais ne résolve que partiellement mon problème.
    Elle m'oblige à traiter les effets qu'après une réponse... Seulement l'effet en question étant un effet de chargement, je dois le lancer avant...

    J'ai donc trouvé le compromis. J'utilise la file d'attente d'effets de scriptaculous pour gérer les effets de Fade in/out en parallèle avec une requête synchrone.

    Tu as bien raison, c'est la seule solution pour bloquer "proprement" la fonction en attente de la réponse.
    Je ne pense pas que ça pose trop de problèmes point de vue "interface". Il faut vraiment avoir une connexion très très lente pour sentir le "freeze"..

    Je te remercie de t'être penché sur le problème ;)

    PS: Oubliez les idées reçues, les requêtes synchrones sont parfois utiles :p

    PPS: Voici le nouveau 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
     
    function treeDrop(srcID, dstID) {
     
    	state_span.innerHTML = 'Déplacement de la catégorie...';
     
    	Effect.Appear(state_div, {duration: 1, queue: 'front'});
     
    	xhr = Ajax.getTransport();
     
    	parameters = 'src_id=' + srcID + '&dest_id=' + dstID;
     
    	xhr.open('POST', 'AJAX/PHP/categories.move.php', false);
     
    	xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
    	xhr.setRequestHeader('Content-length', parameters.length);
    	xhr.setRequestHeader('Connection', 'close');
     
    	xhr.send(parameters);
     
    	Effect.Fade(state_div, {duration: 1, queue: 'end'});
     
    	if (xhr.status == 200) {
     
    		json = eval(xhr.getResponseHeader('X-JSON'));
     
    		if (typeof(json.error) != 'undefined') {
    			widget_show_error(json.error);
    			return false;
    		}
    		else {
    			widget_remove_errors();
    			return true;
    		}
    	}
    	else {
    		return false;
    	}
    }
    C'est bien allegé ;)

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

Discussions similaires

  1. [10g] Fonction stockée et table comme valeur de retour
    Par quaterbac dans le forum PL/SQL
    Réponses: 4
    Dernier message: 06/05/2014, 15h17
  2. Appel de fonctions et récupération de la valeur de retour
    Par Mickael Baron dans le forum Requêtes
    Réponses: 2
    Dernier message: 28/01/2009, 13h57

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