122 votes

jquery - retour de la valeur en utilisant le résultat d'ajax en cas de succès

J'ai un petit problème avec jQuery $.ajax() fonction.

J'ai un formulaire où chaque clic sur le bouton radio ou la sélection dans le menu déroulant crée une variable de session avec la valeur sélectionnée.

Maintenant - j'ai un des menus déroulants qui a 4 options - la première (avec l'étiquette None) a un value="" les autres ont leurs identifiants.

Ce que je veux, c'est que l'option None (avec une valeur vide) supprime la session et que l'autre en crée une, mais seulement si la session avec ce nom de sélection spécifique n'existe pas déjà - car toutes les autres options ont le même montant qui leur est attribué - cela indique simplement laquelle a été sélectionnée.

Je ne suis pas sûr que cela ait un sens - mais jetez un coup d'œil au code - peut-être que cela sera plus clair :

$("#add_ons select").change(function() {
        // get current price of the addons
        var order_price_addon = $(".order_price_addon").text();
        // get price of the clicked radio button from the rel attribute
        var add = $(this).children('option').attr('label');
        var name = $(this).attr('name');
        var val = $(this).val();

        if(val == "") {
            var price = parseInt(order_price_addon) - parseInt(add);
            removeSession(name);
        } else {
            if(isSession(name) == 0) {
                var price = parseInt(order_price_addon) + parseInt(add);
            }   
            setSession(name, val);              
        }

        $(".order_price_addon").html(price);    
        setSession('order_price_addon', price);         
        updateTotal();
});

donc - tout d'abord, lorsque le #add_ons le menu de sélection déclenche "changer" nous obtenons quelques valeurs de quelques éléments pour les calculs.

nous récupérons l'attribut label de l'option de notre sélection qui stocke la valeur à ajouter au total, le nom de la sélection pour créer une session avec ce nom et cette valeur pour vérifier plus tard laquelle a été sélectionnée.

maintenant - nous vérifions si le val == "" (ce qui indiquerait qu'aucune option n'a été sélectionnée) et nous déduisons le montant du total ainsi que nous supprimons la session avec le nom de la personne sélectionnée.

C'est après cela que le problème commence - else déclaration.

Else - nous voulons vérifier si le isSession() avec le nom de notre sélecteur renvoie 0 ou 1 - si elle renvoie 0 alors nous ajoutons au total la valeur stockée dans l'attribut label, mais si elle renvoie 1 - ce qui suggérerait que la session existe déjà - alors nous ne changeons la valeur de cette session qu'en la recréant - mais le montant ne lui est pas ajouté.

Maintenant isSession ressemble à ceci :

function isSession(selector) {
    $.ajax({
        type: "POST",
        url: '/order.html',
        data: ({ issession : 1, selector: selector }),
        dataType: "html",
        success: function(data) {
            return data;
        },
        error: function() {
            alert('Error occured');
        }
    });
}

Maintenant, le problème est que je ne sais pas si l'on peut utiliser return renverra le résultat de la fonction - car cela ne semble pas fonctionner - cependant, si je mets les "données" de la section "success :" dans le champ alert() - il semble renvoyer la bonne valeur.

Quelqu'un sait-il comment retourner la valeur de la fonction et la comparer ensuite dans l'instruction suivante ?


Merci les gars - J'ai essayé de la manière suivante :

function isSession(selector) {
    $.ajax({
        type: "POST",
        url: '/order.html',
        data: ({ issession : 1, selector: selector }),
        dataType: "html",
        success: function(data) {
            updateResult(data);
        },
        error: function() {
            alert('Error occured');
        }
    });
}

alors le updateResult() fonction :

function updateResult(data) {
    result = data;
}

result - est la variable globale - que j'essaie ensuite de lire :

$("#add_ons select").change(function() {
        // get current price of the addons
        var order_price_addon = $(".order_price_addon").text();
        // get price of the clicked radio button from the rel attribute
        var add = $(this).children('option').attr('label');
        var name = $(this).attr('name');
        var val = $(this).val();

        if(val == "") {
            var price = parseInt(order_price_addon) - parseInt(add);
            removeSession(name);
        } else {
            isSession(name);
            if(result == 0) {
                var price = parseInt(order_price_addon) + parseInt(add);
            }   
            setSession(name, val);              
        }

        $(".order_price_addon").html(price);    
        setSession('order_price_addon', price);         
        updateTotal();
    });

mais pour une raison quelconque - cela ne fonctionne pas - une idée ?

0 votes

0 votes

Cela peut aider à résoudre ce problème : stackoverflow.com/questions/14220321/

135voto

user113716 Points 143363

Le problème est que vous ne pouvez pas renvoyer une valeur à partir d'un appel asynchrone, comme une demande AJAX, et espérer que cela fonctionne.

La raison en est que le code qui attend la réponse a déjà été exécuté au moment où la réponse est reçue.

La solution à ce problème consiste à exécuter le code nécessaire dentro de le site success: le rappel. De cette façon, il accède au data uniquement lorsqu'il est disponible.

function isSession(selector) {
    $.ajax({
        type: "POST",
        url: '/order.html',
        data: ({ issession : 1, selector: selector }),
        dataType: "html",
        success: function(data) {
            // Run the code here that needs
            //    to access the data returned
            return data;
        },
        error: function() {
            alert('Error occured');
        }
    });
}

Une autre possibilité (qui revient au même) est d'appeler une fonction à l'intérieur de votre fichier success: callback qui transmet les données lorsqu'elles sont disponibles.

function isSession(selector) {
    $.ajax({
        type: "POST",
        url: '/order.html',
        data: ({ issession : 1, selector: selector }),
        dataType: "html",
        success: function(data) {
                // Call this function on success
            someFunction( data );
            return data;
        },
        error: function() {
            alert('Error occured');
        }
    });
}

function someFunction( data ) {
    // Do something with your data
}

15 votes

Vous POUVEZ renvoyer une valeur à partir d'une requête AJAX, mais seulement si vous la rendez non asynchrone (définir l'option async: false ). Dans certains cas, il n'est pas nécessaire d'avoir un appel asynchrone. Plus d'informations sur la doc jquery.ajax() api.jquery.com/jQuery.ajax pas que As of jQuery 1.8, the use of async: false with jqXHR ($.Deferred) is deprecated;

57 votes

"Non-asynchrone" peut bien sûr aussi être qualifié de "synchrone" ;)

0 votes

Dans les deux méthodes que vous avez suggérées, c'est-à-dire exécuter la fonction avec succès, alors vous devez écrire plusieurs ajax pour différents scénarios. cela ne vous aidera pas à créer un wrapper ajax global, moteur.

41voto

Neeraj Singh Points 1478

Il existe de nombreuses façons d'obtenir une réponse AJAX de jQuery. Je vais partager avec vous deux approches communes :

D'abord :

utiliser async=false et dans la fonction, retourner ajax-object et plus tard obtenir réponse ajax-object.responseText

/**
 * jQuery ajax method with async = false, to return response
 * @param  {mix}  selector - your selector
 * @return {mix}           - your ajax response/error
 */
function isSession(selector) {
    return $.ajax({
        type: "POST",
        url: '/order.html',
        data: {
            issession: 1,
            selector: selector
        },
        dataType: "html",
        async: !1,
        error: function() {
            alert("Error occured")
        }
    });
}
// global param
var selector = !0;
// get return ajax object
var ajaxObj = isSession(selector);
// store ajax response in var
var ajaxResponse = ajaxObj.responseText;
// check ajax response
console.log(ajaxResponse);
// your ajax callback function for success
ajaxObj.success(function(response) {
    alert(response);
});

Deuxièmement :

utiliser $.extend et créer une nouvelle fonction comme ajax

/**
 * xResponse function
 *
 * xResponse method is made to return jQuery ajax response
 * 
 * @param  {string} url   [your url or file]
 * @param  {object} your ajax param
 * @return {mix}       [ajax response]
 */
$.extend({
    xResponse: function(url, data) {
        // local var
        var theResponse = null;
        // jQuery ajax
        $.ajax({
            url: url,
            type: 'POST',
            data: data,
            dataType: "html",
            async: false,
            success: function(respText) {
                theResponse = respText;
            }
        });
        // Return the response text
        return theResponse;
    }
});

// set ajax response in var
var xData = $.xResponse('temp.html', {issession: 1,selector: true});

// see response in console
console.log(xData);

vous pouvez le faire aussi grand que vous voulez...

0 votes

Bonne idée mais ajaxObj['responseText'] n'existe pas lorsque vous définissez var ajaxResponse

0 votes

Parfait ! !! votre première solution m'a sauvé

0 votes

La deuxième méthode est 100% A OK ! ;)

8voto

aesede Points 97

EDIT : C'est assez vieux, et moche, ne faites pas ça. Vous devriez utiliser des callbacks : https://stackoverflow.com/a/5316755/591257

EDIT 2 : Voir le récupérer l'API

J'ai eu le même problème, je l'ai résolu de cette façon, en utilisant une variable globale. Je ne suis pas sûr que ce soit la meilleure solution, mais elle fonctionne. En cas d'erreur, vous obtenez une chaîne vide (myVar = ''), vous pouvez donc la gérer comme vous le souhaitez.

var myVar = '';
function isSession(selector) {
  $.ajax({
    'type': 'POST',
    'url': '/order.html',
    'data': {
      'issession': 1,
      'selector': selector
    },
    'dataType': 'html',
    'success': function(data) {
      myVar = data;
    },
    'error': function() {
      alert('Error occured');
    }
  });
  return myVar;
}

9 votes

Vous devez également ajouter async: false ici, parce qu'en mode asynchrone il n'est pas garanti que data est enregistré dans myVar avant myVar est renvoyé.

0 votes

@low_rents, merci pour ce commentaire. J'ai eu un problème pour renvoyer une valeur à partir d'un appel ajax et c'est le premier fil de discussion que j'ai trouvé (après beaucoup d'autres) qui mentionnait async: false . Cela a parfaitement fonctionné pour moi.

0 votes

Absolument @low_rents mais ne vous fiez pas à cette réponse, les choses ont beaucoup évolué depuis.

3voto

Hoodlum Points 19

Ajouter async: false à votre liste d'attributs. Cela oblige le thread javascript à attendre que la valeur de retour soit récupérée avant de poursuivre. Évidemment, vous ne voudriez pas faire cela dans toutes les circonstances, mais si une valeur est nécessaire avant de continuer, cela le fera.

4 votes

Vous ne devriez jamais mettre async: false . Cela bloque tout ce qui se trouve sur la page pendant la durée de l'extraction. Vous savez ce que signifie le A dans AJAX : Asynchrone. La bonne réponse serait que le PO doit utiliser la fonction success() correctement.

2 votes

J'ai reconnu le fait que tout doit attendre. Dans certaines circonstances, la fonction appelante peut avoir besoin d'une valeur renvoyée, comme par exemple l'ajout d'un nouvel enregistrement et la nécessité de renvoyer un identifiant d'enregistrement. Une fois que vous connaissez les règles, vous savez quand elles peuvent être enfreintes. Il ne faut jamais dire jamais. Voici quelqu'un d'autre qui est d'accord. ( stackoverflow.com/questions/3880361/ )

0 votes

Là aussi, on se trompe, le problème décrit pourrait être résolu facilement de manière asynchrone. Vous ne gagnez rien à faire des appels synchrones, au contraire.

2voto

Binson Points 11
// Common ajax caller
function AjaxCall(url,successfunction){
  var targetUrl=url;
  $.ajax({
    'url': targetUrl,
    'type': 'GET',
    'dataType': 'json',
    'success': successfunction,
    'error': function() {
      alert("error");
    }
  });
}

// Calling Ajax
$(document).ready(function() {
  AjaxCall("productData.txt",ajaxSuccessFunction);
});

// Function details of success function
function ajaxSuccessFunction(d){
  alert(d.Pioneer.Product[0].category);
}

cela peut vous aider, créez une fonction d'appel ajax commune et attachez une fonction qui sera invoquée lorsque l'appel ajax sera réussi, voir l'exemple suivant

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X