2010-07-21 13 views
64

Mam mały problem z funkcją jquery $ .ajax().jquery - wartość zwracana za pomocą wyniku ajaxowego na sukces

Mam formularz, w którym każde kliknięcie przycisku opcji lub menu rozwijanego tworzy zmienną sesji z wybraną wartością.

Teraz - Mam jedno z menu rozwijanych, które ma 4 opcje - pierwsza (z etykietą Brak) ma wartość = "" inne mają ich identyfikatory.

Co chcę zrobić, to opcja Brak (z pustą wartością), aby usunąć sesję i inną, aby utworzyć sesję, ale tylko wtedy, gdy sesja o tej konkretnej nazwie wyboru jeszcze nie istnieje - ponieważ wszystkie inne opcje mają takie same kwota do niego przypisana - wskazuje tylko, który z nich został wybrany.

Nie jestem pewien, czy to ma sens - ale rzucić okiem na kod - może to będzie to jaśniej:

$("#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(); 
}); 

więc - przede wszystkim gdy #add_ons wybierz menu powoduje zmianę” "otrzymujemy pewne wartości z kilku elementów do obliczeń.

otrzymamy atrybut etykiety opcji z naszego wyboru, który przechowuje wartość, która ma zostać dodana do sumy, nazwę zaznaczenia, aby utworzyć sesję o tej nazwie i wartości, aby później sprawdzić, który z nich został wybrany.

teraz - sprawdzamy, czy wartość == "" (co wskazuje, że wybrano opcję Brak), odliczamy kwotę z sumy, a także usuwamy sesję z nazwą wyboru.

Po tym zaczyna się problem - instrukcja else.

Else - chcemy sprawdzić, czy funkcja isSession() z nazwą naszego selektora zwraca 0 lub 1 - jeśli zwraca 0, dodajemy do sumy wartość przechowywaną w atrybucie label, ale jeśli zwraca 1 - to sugeruje, że sesja już istnieje - wtedy zmieniamy wartość tej sesji tylko poprzez jej odtworzenie - ale kwota nie jest do niej dodawana.

funkcja

Teraz isSession wygląda następująco:

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'); 
     } 
    }); 
} 

Teraz - problemem jest to - że nie wiem, czy za pomocą „zwrot” zwróci wynik z funkcji - jak to nie wydaje się pracować - jeśli jednak umieściłem "dane" w sukcesie: sekcja w alarmie - wydaje się, że zwraca właściwą wartość.

Czy ktoś wie, jak zwrócić wartość z funkcji, a następnie porównać ją w następnej instrukcji?


Dzięki chłopaki - Próbowałem go w następujący sposób:

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'); 
     } 
    }); 
} 

wtedy updateResult() funkcja:

funkcja updateResult (data) {result = dane; }

wynik - to zmienna globalna - co ja wtedy próbuje odczytać:

$("#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(); 
    }); 

ale z jakiegoś powodu - nie działa - jakiś pomysł?

+0

możliwe duplikat [Jak zwrócić odpowiedź z AJAX zadzwonić?] (http://stackoverflow.com/questions/14220321/how-to-return--response-od-an-ajax-call) – Bergi

+16

'Mam mały problem z jquery ....' Jest to najdłuższy mały problem Widziałem kiedykolwiek ...;) – prageeth

Odpowiedz

86

Problem polega na tym, że nie można zwrócić wartości z wywołania asynchronicznego, np. Żądania AJAX, i oczekiwać, że zadziała.

Powód jest taki, że kod oczekujący na odpowiedź został już wykonany do czasu otrzymania odpowiedzi.

Rozwiązaniem tego problemu jest uruchomienie wymaganego kodu wewnątrz wywołania zwrotnego success:. W ten sposób uzyskuje dostęp do data tylko wtedy, gdy jest dostępny.

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'); 
     } 
    }); 
} 

Inna możliwość (co jest skutecznie to samo) jest wywołanie funkcji wewnątrz success: zwrotnego, który przekazuje dane, gdy jest ona dostępna.

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 
} 
+7

Możesz zwrócić wartość z żądania AJAX, ale to tylko jeśli uczynisz to * niesynchronicznym * (ustaw opcję 'async: false'). W niektórych przypadkach wywołanie asynchroniczne nie jest wymagane. Więcej o jquery.ajax() doc http://api.jquery.com/jQuery.ajax/, nie że "Od jQuery 1.8, użycie async: false z jqXHR ($ .deferred) jest przestarzałe;' –

+31

" Nie asynchroniczne "można oczywiście również nazywać" synchronicznym ";) –

+0

w obu metodach, które zasugerowałeś; to znaczy. uruchom funkcję z powodzeniem, następnie musisz napisać wiele ajax dla różnych scenariuszy. to nie pomoże w stworzeniu globalnego mechanizmu pakowania ajaxów. – wpcoder

26

Istnieje wiele sposobów na uzyskanie odpowiedzi ajax jQuery. Dzielę się z wami dwa wspólne approch:

pierwsze:

korzystanie asynchroniczny = false iw powrotną Ajax obiektu i później dostać odpowiedź 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); 
}); 

Po drugie:

użycie $ .extend sposób i zrobić nową funkcję jak 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); 

można zrobić to tak duży, jak chcesz ...

+0

Dobry pomysł, ale 'ajaxObj ['responseText']' nie istnieje, gdy definiujesz 'var ajaxResponse' – mu3

+0

Perfect !! twoje pierwsze rozwiązanie uratowało mnie –

+0

druga metoda to 100% A OK! ;) –

2

To jest dość stary i brzydkie, nie rób tego. Powinieneś użyć wywołań zwrotnych: https://stackoverflow.com/a/5316755/591257
Miałem ten sam problem, rozwiązany w ten sposób, używając globalnego var. Nie jestem pewien, czy to najlepsze, ale na pewno działa. W przypadku błędu otrzymasz pusty ciąg (myVar = ''), więc możesz go obsłużyć w razie potrzeby.

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; 
} 
+2

musisz również dodać tutaj 'async: false', ponieważ w trybie asynchronicznym nie ma gwarancji, że' data' zostanie zapisana w 'myVar' przed zwróceniem' myVar'. –

1
// 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); 
} 

może pomóc stworzyć wspólną funkcję wywołania AJAX i załączyć funkcję, która powoływania gdy sukces wywołania AJAX, zobacz przykład

3

Dodaj async: false do listy atrybutów. Zmusza to wątek javascript do oczekiwania na powrót do wartości zwracanej przed przejściem. Oczywiście nie chciałbyś tego robić w każdych okolicznościach, ale jeśli potrzebna jest wartość, zanim to zrobisz, zrobi to.

+2

Nigdy nie powinieneś ustawiać 'async: false'. Blokuje to wszystko na stronie w czasie pobierania. Wiesz, co oznacza A w AJAX: Asynchroniczne. Prawidłowa odpowiedź brzmi, że OP musi poprawnie używać wywołania zwrotnego 'success()'. – nietonfir

+2

Uznałem fakt, że wszystko musi poczekać. W pewnych okolicznościach funkcja wywołująca może potrzebować zwróconej wartości, takiej jak dodanie nowego rekordu i wymaganie zwróconego identyfikatora rekordu. Gdy znasz zasady, wiesz, kiedy mogą zostać złamane. Nigdy nie mów nigdy. Oto ktoś inny, który się zgadza. (http://stackoverflow.com/questions/3880361/returning-the-response-from-an-jquery-ajax-call) – Hoodlum

+0

Powoduje to również błąd, opisany problem można łatwo rozwiązać w sposób asynchroniczny. Nic nie zyskujesz, wykonując połączenia synchroniczne, wręcz przeciwnie. – nietonfir

0

Hi spróbować async: false w ajax rozmowy ..

+0

przestarzałe od jquery 1.8 jako @mikewee wskazał. – wpcoder

4

Widziałem tutaj odpowiedzi i choć pomocne, nie były one dokładnie to, co chciałem, ponieważ musiałem zmieniać dużo mojego kodu.

Co pracował dla mnie, robił coś takiego:

function isSession(selector) { 
    //line added for the var that will have the result 
    var result = false; 
    $.ajax({ 
     type: "POST", 
     url: '/order.html', 
     data: ({ issession : 1, selector: selector }), 
     dataType: "html", 
     //line added to get ajax response in sync 
     async: false, 
     success: function(data) { 
      //line added to save ajax response in var result 
      result = data; 
     }, 
     error: function() { 
      alert('Error occured'); 
     } 
    }); 
    //line added to return ajax response 
    return result; 
} 

Nadzieja pomaga komuś

Anakin

+2

Po prostu wyłączasz asynchronizację –

Powiązane problemy