2012-12-12 17 views
5

NAPRAWIONA! DZIĘKI! Zobacz "Poprawiony kod" poniżej.jQuery Wartość zwrotu niezdefiniowana

Celem jest odzyskanie danych z okna dialogowego. Widziałem wiele artykułów, ale nie udało mi się uzyskać żadnego z nich, więc zdecydowałem się użyć usługi internetowej, aby przekazywać dane w obie strony między oknem dialogowym a stroną bazową.

Cały kod jest na miejscu, z wyjątkiem kodu, który odczytuje wartości wracające z usługi internetowej. W debugerze widzę, że dane są przekazywane, ale kiedy wracam do wywołującego, zwrócone dane są niezdefiniowane.

Funkcja jQuery getLocal wywołuje funkcję AJAX, odzyskuje dane, ale po powrocie do funkcji, która je wywołuje (verbListShow), zwrócona wartość jest "niezdefiniowana".

To wszystko dzieje się na stronie ASP.NET, która jest napisana głównie w jQuery i otwiera okno dialogowe jQuery.

function getLocal(name) { 
    $.ajax({ 
     type: "POST", 
     async: false, 
     url: "WebServices/FLSAService.asmx/GetLocalVariable", 
     dataType: 'json', 
     contentType: 'application/json; charset=utf-8', 
     data: JSON.stringify({ name: name }), 
     success: function (data) { 
      var rtn = data.d; 
      return rtn; 
     } 
    }); 
} 

Powyższy kod działa, ale po wywołaniu, rtn jest niezdefiniowany. Oto rozmówcy:

function verbListShow(dutyNumber) { 

    $('#dlgDutyList').dialog({ 
     modal: true, 
     show: "slide", 
     width: 250, 
     height: 250, 
     open: function (event, ui) { 
      setLocal("DUTYNUMBER", dutyNumber); 
     }, 
     buttons: { 
      "Select": function() { 
       var id = getLocal("VERBID"); // <*** Returns undefined 
       var verb = getLocal("VERB"); // <*** Returns undefined 
       $.ajax({ 
        type: "POST", 
        async: false, 
        url: "WebServices/FLSAService.asmx/SetDuty", 
        dataType: 'json', 
        contentType: 'application/json; charset=utf-8', 
        data: JSON.stringify({ dutyNum: dutyNumber, id: id, verb: verb }), 
        success: function (data) { 
         data = $.parseJSON(data.d); 
         if (data.ErrorFound) { 
          showMessage(data.ErrorMessage, 2, true); 
         } 
         else { 
          log('Set Duty: ' + data.StringReturn + ' (' + data.intReturn + ')'); 
         } 
        }, 
        error: function (XMLHttpRequest, textStatus, errorThrown) { 
         alert("updateDuty: " 
          + XMLHttpRequest.responseText); 
        } 
       }); 

       $(this).dialog("close"); 
      }, 
      Cancel: function() { 
       $(this).dialog("close"); 
      } 
     } 

    }); 
    $('#dlgDutyList').dialog('open'); 

ustalony kod:

function getLocal(name) { 
var rtn = ""; 
    $.ajax({ 
     type: "POST", 
     async: false, 
     url: "WebServices/FLSAService.asmx/GetLocalVariable", 
     dataType: 'json', 
     contentType: 'application/json; charset=utf-8', 
     data: JSON.stringify({ name: name }), 
     success: function (data) { 
      rtn = data.d; 
     } 
    }); 
return rtn; 
} 
+0

Co zwraca usługa internetowa po umieszczeniu w niej nazwy? Czy ma w sobie d pole? pokaż niektóre przykładowe dane. –

+0

'return rtn;' Nie można powrócić z wywołania zwrotnego sukcesu ajax. Sugeruję albo nie używając funkcji getLocal, albo zwracając obiekt jqXHR. –

Odpowiedz

6

on celowość AJAX go używać synchronicznie (AJAX oznacza Asynchronous JavaScript and XML).

Teraz nie można return wartość od metody sukces, ale można przechowywać ją w zmiennej, a następnie powrócić że

function getLocal(name) { 
    var returnValue; 
    $.ajax({ 
     type: "POST", 
     async: false, 
     url: "WebServices/FLSAService.asmx/GetLocalVariable", 
     dataType: 'json', 
     contentType: 'application/json; charset=utf-8', 
     data: JSON.stringify({ name: name }), 
     success: function (data) { 
      returnValue = data.d; 
     } 
    }); 
    return returnValue; 
} 

Ale właściwa sposób byłoby użyć deferred object

function getLocal(name, resultset) { 
    return $.ajax({ 
     type: "POST", 
     url: "WebServices/FLSAService.asmx/GetLocalVariable", 
     dataType: 'json', 
     contentType: 'application/json; charset=utf-8', 
     data: JSON.stringify({ name: name }), 
     success: function (data) { 
      resultset[name] = data.d; 
     } 
    }); 
} 

i nazwać

"Select": function() { 
    var results = {}; 
    var self = this; 
    $.when(getLocal("VERBID", results), getLocal("VERB", results)).then(function(){ 
     $.ajax({ 
      type: "POST", 
      url: "WebServices/FLSAService.asmx/SetDuty", 
      dataType: 'json', 
      contentType: 'application/json; charset=utf-8', 
      data: JSON.stringify({ 
       dutyNum: dutyNumber, 
       id: results.VERBID, 
       verb: results.VERB 
      }), 
      success: function(data) { 
       data = $.parseJSON(data.d); 
       if (data.ErrorFound) { 
        showMessage(data.ErrorMessage, 2, true); 
       } 
       else { 
        log('Set Duty: ' + data.StringReturn + ' (' + data.intReturn + ')'); 
       } 
      }, 
      error: function(XMLHttpRequest, textStatus, errorThrown) { 
       alert("updateDuty: " + XMLHttpRequest.responseText); 
      } 
     }); 
    }).always(function(){ 
     $(self).dialog("close"); 
    }); 
} 
3

Wszystko dlatego, że funkcja $ .ajax nie zwraca żadnej wartości ze względu na jej asynchroniczne zachowanie. Moją wskazówką jest uczynienie drugiego parametru dla metody getLocal zwanej "callback".

Właściwa droga jest zrobić to tak:

function getLocal(name, callback) { 
    $.ajax({ 
     type: "POST", 
     async: false, 
     url: "WebServices/FLSAService.asmx/GetLocalVariable", 
     dataType: 'json', 
     contentType: 'application/json; charset=utf-8', 
     data: JSON.stringify({ name: name }), 
     success: function (data) { 
      var rtn = data.d; 
      callback(rtn); 
     } 
    }); 
} 

Następnie głównym kod musi wyglądać tak (kod asynchroniczny):

//some code here 
buttons: { 
      "Select": function() { 
       getLocal("VERBID", function(id) { 
        getLocal("VERB", function(verb) { 
         $.ajax({ 
          type: "POST", 
          async: false, 
          url: "WebServices/FLSAService.asmx/SetDuty", 
          dataType: 'json', 
         //some code here 
        }); 
       }); 
//some code here 

Aby poprawić ten kod, aby dwa wywołań asynchronicznych jednocześnie, można użyć obiektu jQuery Deferred i uruchomić na nim .resolve(data) zaraz po wywołaniu właściwej odpowiedzi przez wywołania ajax.

+0

Podziękowania dla obu respondentów. Dostałem kod działający szybko z powodu twojej pomocy. –