2010-06-23 63 views
1

我有一個函數runAjax,它可以正常工作。不幸的是我掙扎着返回從ajax查詢中獲得的值。JQuery AJAX函數的工作原理,但無法正確返回變量

ajax函數將「contents」或「error」xml標記內的返回值賦給變量「result」。

如果我警告ajax函數內的結果變量,它會提示正確的值(即如果內容中的xml值是「已發佈」,它會發布警報)。

但是,如果我警告從runAjax函數返回的值,它會警告一個對象,而不是上面示例中「發佈」的內部變量「result」的值。

function runAjax (data_obj){ 
    return $.ajax({ 
     url:"/ajax.php", 
     dataType: "xml", 
     data: data_obj, 
     success: function(data) { 
     // format result 
     var xml; 
     if (typeof data == "string") { 
      xml = new ActiveXObject("Microsoft.XMLDOM"); 
      xml.async = false; 
      xml.loadXML(data); 
     } else { 
      xml = data; 
     } 
     var result; 
     if($("error",xml).text()){ 
      result = [$("error",xml).text()]; 
     } else{ 
      result = [ 
      $("contents", xml).text() 
      ]; 
     } 
     alert(result); //alerts the correct string for example "published" 
     return result; 
     } 
    }); 
    } 
    $('ul.content li span.changeable').click(function(e){ 
    e.preventDefault(); 
    var method_set = $(this).parent().attr("class"); 
    var id_set = $(this).parent().parent().find('li.id span').html(); 
    var user = $(this); 
    var result = runAjax({method: method_set, id: id_set}); 
    alert(result); //alerts an object not published 

    }); 

我確定它與我返回變量的方式有關,但我無法弄清楚。任何輸入將不勝感激。

問候 盧克

UPDATE: 這是從人以下的作品感謝所有輸入修改後的代碼:

function runAjax (data_obj,callback){ 
    $.ajax({ 
     url:"/ajax.php", 
     dataType: "xml", 
     data: data_obj, 
     success: function(data) { 
     // format result 
     var xml; 
     if (typeof data == "string") { 
      xml = new ActiveXObject("Microsoft.XMLDOM"); 
      xml.async = false; 
      xml.loadXML(data); 
     } else { 
      xml = data; 
     } 
     var result; 
     if($("error",xml).text()){ 
      result = [$("error",xml).text()]; 
     } else{ 
      result = [ 
      $("contents", xml).text() 
      ]; 
     } 
     if (typeof(callback) == "function") { 
      callback(result); 
     } 
     } 
    }); 
    } 
    $('ul.content li span.changeable').click(function(e){ 
    e.preventDefault(); 
    var method_set = $(this).parent().attr("class"); 
    var id_set = $(this).parent().parent().find('li.id span').html(); 
    var user = $(this); 
    runAjax({ 
     method: method_set, 
     id: id_set 
    }, 
    function(result){ 
     $(user).html(result.join('')); //this is instead of alert(result); 
    } 
    ); 

    }); 

回答

4

按照docs

的$阿賈克斯()函數返回它創建的XMLHttpRequest對象。

從成功回調函數返回的任何返回值都被忽略。

您需要將該值放在比回調函數(全局函數,或最好在一個外部函數內)更廣泛的範圍內定義的變量中。

var result; 
    $.ajax({ 
     .... 
     success : function(data) { 
      ... 
      result = ...; 
     } 
    }); 

或者更好的是:做任何你想要的成功回調函數中的返回值做的,這將讓Ajax調用的異步性,並意味着你不需要等待調用回來。

在成功回調函數中進行處理意味着你知道你已經得到了結果,如果你將該值放入一個變量中,那麼當你想要使用該變量時,變量可能不會被分配一個值。

在此頁面上的另一個答案評論你說:

不過我打電話從其他多種功能不只是一個在我上面的代碼示例runAjax功能,所以我需要返回的值,而比runAjax功能做HTML更換

我會添加一個額外的參數,你runAjax功能,這是另一個回調函數,你可以在不同的處理功能通過從各種功能。

function runAjax(data_obj, callback) { 
    $.ajax({ 
     ... 
     success : function(data) { 
      ... 
      result = ... 
      ... 
      if (typeof(callback) == "function") { 
       callback(result); 
      } 
     } 
    }); 
} 

然後,你可以這樣調用它

runAjax({method: method_set, id: id_set}, 
    function(result){ 
     alert(result); 
    } 
); 

然後,你可以做你的成功的功能數據的通用處理,但在回調函數每次調用自定義處理。

如果你真的需要等待調用,你可以通過異步選項來創建一個同步Ajax調用:

$.ajax({ 
    async:false, 
    .... 
+0

我沒有考慮過使用同步調用,因爲它通常不合適,但如果沒有其他選項,它可能是處理事情的有效方法。取決於發佈的AJAX處理要求是什麼。 – belugabob 2010-06-23 13:42:13

+0

感謝馬里奧,你所做的最後一次編輯只是縮小了你的答案,因爲我不想在每次調用函數時寫出整個成功函數。非常感謝你的魅力。 – Luke 2010-06-23 14:04:38

0

嘗試刪除[]

if($("error",xml).text()){ 
     result = $("error",xml).text(); 
    } else{ 
     result = $("contents", xml).text(); 
    } 
+0

嗨,感謝您的答案,不幸的是這並沒有奏效。 – Luke 2010-06-23 13:35:17

1

盧克,

我認爲你在函數中的錯誤點分配了重試值,你應該在最後的大括號之前有一個單獨的出口點。您在技術上返回結果作爲$ .ajax()函數(一個XMHTTP對象)的返回值,而不是父方法。

試試這個:

function runAjax (data_obj){ 
    var returnValue; 
    $.ajax({ 
     url:"/ajax.php", 
     dataType: "xml", 
     data: data_obj, 
     success: function(data) { 
      // format result 
      var xml; 
      if (typeof data == "string") { 
       xml = new ActiveXObject("Microsoft.XMLDOM"); 
       xml.async = false; 
       xml.loadXML(data); 
      } else { 
       xml = data; 
      } 
      var result; 
      if($("error",xml).text()){ 
       result = [$("error",xml).text()]; 
      } else{ 
       result = [ 
       $("contents", xml).text() 
       ]; 
      } 
      alert(result); //alerts the correct string for example "published" 
      returnValue = result; 
     } 
    }); 
    return returnValue; 
} 
$('ul.content li span.changeable').click(function(e){ 
    e.preventDefault(); 
    var method_set = $(this).parent().attr("class"); 
    var id_set = $(this).parent().parent().find('li.id span').html(); 
    var user = $(this); 
    var result = runAjax({method: method_set, id: id_set}); 
    alert(result); //alerts an object not published 

}); 
+0

嗨吉姆,我剛剛走了,不幸的是,我得到了與我原來的代碼 – Luke 2010-06-23 13:38:23

+0

盧克相同的結果,我真的明白了爲什麼它不會在上述情況下工作。基本上,$。ajax()方法是異步的,所以返回值將在成功調用之前返回。我會在單獨的筆記中放下我用於這種有趣的'模式'的註釋。 – 2010-06-23 13:41:13

+0

這是因爲var result = runAjax()將分配對XMLHttpRequest對象的引用 - 而不是您想要的值。 – belugabob 2010-06-23 13:43:47

1

,你不能得到結果的原因返回正確是因爲AJAX的異步性(這是第一個「A」表示)。

在AJAX操作完成並調用'success'處理程序之前,對runAjax()的調用可能會返回很久。 runAjax()調用將引用返回給用於調用AJAX通信的XMLHttpRequest對象。成功處理程序的返回值不能直接用於您,因爲它返回到$ .ajax()代碼的內部工作。

一個合適的解決方案將取決於你想要做什麼'結果' - 我猜'alert(result)'僅用於說明目的。

+0

有沒有辦法讓我等待ajax響應? – Luke 2010-06-23 13:35:36

+0

是的 - 這就是'成功'功能的原因 - 當AJAX響應提供時它會被調用。 – belugabob 2010-06-23 13:40:10

+0

嗨Belugabob,與返回的值我正在替換一些html內容,但是我從多個其他函數調用runAjax函數不只是我的代碼示例上面,所以我需要返回的值而不是runAjax函數做HTML更換。那有意義嗎?對不起,如果它不清楚。 – Luke 2010-06-23 13:40:31

2

盧克,

基本上,爲您的$的包裝功能。阿賈克斯()的回調部分對應的參數調用(你當然可以有在Ajax調用任何有效的放慢參數參數這裏的匆匆證明:

function runAjax (data_obj, callback){ 
    $.ajax({ 
     url:"/ajax.php", 
     dataType: "xml", 
     data: data_obj, 
     success: function(data) { 
      if (data != null && callback !== null) { 
       callback(data); 
      } 
     } 
    }); 
} 

function callbackFunction (data) { 
    // format result 
    var xml; 
    if (typeof data == "string") { 
     xml = new ActiveXObject("Microsoft.XMLDOM"); 
     xml.async = false; 
     xml.loadXML(data); 
    } else { 
     xml = data; 
    } 
    var result; 
    if($("error",xml).text()){ 
     result = [$("error",xml).text()]; 
    } else{ 
     result = [ 
     $("contents", xml).text() 
     ]; 
    } 
    alert(result); //alerts the correct string for example "published" 
    // do your DOM updates etc here 
} 

$('ul.content li span.changeable').click(function(e){ 
    e.preventDefault(); 
    var method_set = $(this).parent().attr("class"); 
    var id_set = $(this).parent().parent().find('li.id span').html(); 
    var user = $(this); 
    runAjax({method: method_set, id: id_set}, callbackFunction); 
}); 

希望這有助於..

+0

偉大的思想家都認爲。 (John Resig肯定有一個很好的想法):-) – belugabob 2010-06-23 13:57:11

+0

感謝Jim,這是一個很好的幫助,我只是不想爲每個runAjax調用聲明一個像你的callbackFunction這樣的大函數,+1幫忙,謝謝 – Luke 2010-06-23 14:07:08

+0

盧克 - 爲了完整性,你可以用修改後的代碼更新你的問題(作爲它下面的更新),因爲它可以幫助人們看到'前後' - 謝謝.. jim – 2010-06-23 14:13:24

0

盧克, 爲了進一步完善了我和Jim提供的答案,考慮到結果解析位很可能是針對每個不同的呼叫一致...

function runAjax (data_obj, callback){ 
    $.ajax({ 
     url:"/ajax.php", 
     dataType: "xml", 
     data: data_obj, 
     success: function(data) { 
      if (data != null && callback !== null) { 
       // format result 
       var xml; 
       if (typeof data == "string") { 
        xml = new ActiveXObject("Microsoft.XMLDOM"); 
        xml.async = false; 
        xml.loadXML(data); 
       } else { 
        xml = data; 
       } 
       var result; 
       if($("error",xml).text()){ 
        result = [$("error",xml).text()]; 
       } else{ 
        result = [$("contents", xml).text()]; 
       } 
       callback(result); 
      } 
     } 
    }); 
} 

function callbackFunction (result) { 
    alert(result); //alerts the correct string for example "published" 
    // do your DOM updates etc here 
} 

$('ul.content li span.changeable').click(function(e){ 
    e.preventDefault(); 
    var method_set = $(this).parent().attr("class"); 
    var id_set = $(this).parent().parent().find('li.id span').html(); 
    var user = $(this); 
    runAjax({method: method_set, id: id_set}, callbackFunction); 
}); 
+0

嗨Belugabob,這基本上是我最終做的,但回調功能是不一樣的每個runAjax調用,所以我分配在調用函數,而不是全球像你的是,非常感謝輸入,非常有用。 – Luke 2010-06-23 14:16:35

+0

盧克 - 作爲一個最後一邊。我肯定總是試着把回調作爲一個單獨的函數(可能上面是一個完美的實現)。原因是你可能想要處理來自非Ajax調用的相同數據,以進行基本相同的處理。因此你會保持乾爽。 – 2010-06-23 14:25:08

+0

嗨吉姆,在我修改後的代碼中,你可以看到我使用了「用戶」變量,如果我要創建globaly函數,我怎麼能使用這個變量,僅僅是因爲我可能並不總是想用「user」,所以我不用想要將「user」解析爲runAjax的變量。 – Luke 2010-06-23 14:33:05

0

您可以將ajax調用的成功處理爲一個事件,該事件可以保持異步調用的好東西,包括基於您調用的url的東西。

$('ul.content li span.changeable').ajaxSuccess(function(e, xhr, settings) { 
    if (settings.url == '/ajax.php') { 
    $(this).text('Triggered ajaxSuccess handler.'); 
    someglobalresultvariable = xhr.responseXML; // the xml of the response 
    $(this).text(someglobalresultvariable); 
    } 
}); 

在這裏,我假設您想要根據點擊的項目更改跨度內容文本。

注意:我替換了「已觸發的」文本消息,僅以示例的形式顯示。你可以決定你想如何處理結果。

相關問題