2012-04-13 51 views
0

我想寫一個簡單的函數來從JavaScript中加載一個數組的XML。撥打$.ajax(...)時,我已成功地將AJAX結果發送至使用success:字段的功能。用AJAX加載和返回數據以後使用

另外,我注意到,功能$.ajax(...)的返回值是一個Object,其中有場responseTextresponseXML(我會很高興的使用)。但是,儘管我可以在控制檯的樹中看到它們,但試圖通過.responseText訪問它們不起作用(因此打印undefined,如果我嘗試查找某些垃圾字符串.this_does_not_exist)也是如此。

我打算做幾乎與幾個不同的XML文件相同,我想用代碼來做到這一點。我不滿意的原因是success:參數將結果踢到一個單獨的函數,因爲我可能會多次使用這些數據,但只需要加載一次。我試圖分開加載和使用XML,以便它不被加載多次。

你能告訴我爲什麼responseText顯示出來,當我輸出xml_ret,但無法訪問xml_ret.responseText

非常感謝您的幫助和耐心。


注:從同一目錄中加載test.xml,您需要啓動Chrome或鉻是這樣的:

chromium-browser --allow-file-access-from-files 

的test.html:

<html> 
<head> 
<script type="text/javascript" 
     src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> 

    <script type="text/javascript"> 
     function print_XML(xml) 
     { 
     console.log("in printXML"); 
     console.log(xml); 

     $(xml).find("point").each(function() 
     { 
     var loaded_row = [ parseInt($(this).attr("number_protein_groups")), parseInt($(this).attr("log_likelihood")) ]; 
     console.log(loaded_row); 
     }); 
     } 

     function load_and_print_XML(fname) 
     { 
    console.log("in load_and_print_XML"); 

     xml_ret = $.ajax({ 
     type: "GET", 
     url: fname, 
     dataType: "xml", 
     success: print_XML 
     }); 

    console.log("xml_ret"); 
    console.log(xml_ret); 
    console.log(xml_ret.responseText); 
     } 

    </script> 

</head> 
    <body> 
    <script type="text/javascript"> 
     xml_data = load_and_print_XML("test.xml"); 
     /* do something with xml_data here */ 
    </script> 
    </body> 
</html> 

test.xml

<?xml version="1.0" encoding="utf-8" ?> 
<results> 
    <replicate_result graph_filename="yeast_1.pivdo"> 
    <point number_protein_groups="10" log_likelihood="20"/> 
    <point number_protein_groups="20" log_likelihood="40"/> 
    <point number_protein_groups="40" log_likelihood="60"/> 
    <point number_protein_groups="50" log_likelihood="50"/> 
    <point number_protein_groups="60" log_likelihood="55"/> 
    </replicate_result> 
</results> 

我的控制檯:

in load_and_print_XML 
test.html:30xml_ret 
test.html:31 
Object 
abort: function (a){a=a||"abort",p&&p.abort(a),w(0,a);return this} 
always: function(){i.done.apply(i,arguments).fail.apply(i,arguments);return this} 
complete: function(){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this} 
done: function(){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this} 
error: function(){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this} 
fail: function(){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this} 
getAllResponseHeaders: function(){return s===2?n:null} 
getResponseHeader: function (a){var c;if(s===2){if(!o){o={};while(c=bG.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c} 
isRejected: function(){return!!i} 
isResolved: function(){return!!i} 
overrideMimeType: function (a){s||(d.mimeType=a);return this} 
pipe: function (a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()} 
progress: function(){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this} 
promise: function (a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a} 
readyState: 4 
responseText: "<?xml version="1.0" encoding="utf-8" ?>↵<results>↵ <replicate_result graph_filename="yeast_1.pivdo">↵ <point number_protein_groups="10" log_likelihood="20"/>↵ <point number_protein_groups="20" log_likelihood="40"/>↵ <point number_protein_groups="40" log_likelihood="60"/>↵ <point number_protein_groups="50" log_likelihood="50"/>↵ <point number_protein_groups="60" log_likelihood="55"/>↵ </replicate_result>↵</results>" 
responseXML: Document 
setRequestHeader: function (a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this} 
state: function(){return e} 
status: 200 
statusCode: function (a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this} 
statusText: "success" 
success: function(){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this} 
then: function (a,b,c){i.done(a).fail(b).progress(c);return this} 
__proto__: Object 
test.html:32undefined 
test.html:9in printXML 
test.html:10 
Document 
<results>​ 
<replicate_result graph_filename=​"yeast_1.pivdo">​…​</replicate_result>​ 
</results>​ 
test.html:15[10, 20] 
test.html:15[20, 40] 
test.html:15[40, 60] 
test.html:15[50, 50] 
test.html:15[60, 55] 

回答

2

的問題:

你能告訴我爲什麼responseText的顯示出來,當我輸出xml_ret,但不能訪問由 xml_ret.responseText?

這是因爲當你做一個對象的console.log,例如在chrome中,它保持對控制檯中對象的引用。如果對象發生變化,則這些更改將由Chrome控制檯反映出來。

那麼是什麼發生的事情是,當你做:

console.log("xml_ret"); 
console.log(xml_ret); 
console.log(xml_ret.responseText); 

Ajax請求還沒有完成,這個responseText仍然尚未分配,這就是爲什麼它顯示爲未定義。但是,打印的xml_ret對象是對對象的引用,所以當ajax請求完成時,如果您要檢查控制檯上的值,它將具有「responseText」屬性,因爲它已被設置。

你可以看到,如果你調試代碼,並在此行中添加斷點:

console.log(xml_ret.responseText); 

當在文件中查找xml_ret它不具備「responseText的」屬性。

PS:我需要仔細閱讀此評論。太遲了也認爲:P

+0

+1正確的人,另一個用戶誰瞭解它! – noob 2012-04-13 23:15:51

+1

謝謝! 事實上,當你試圖訪問它的屬性時,chrome的控制檯似乎會評估這個對象。 如果在ajax請求完成之前調試並嘗試查看xml_ret屬性,則responseText不會出現,並且以後不會更改。但是,如果您第一次嘗試訪問屬性是在ajax請求完成後顯示responseText。 – txominpelu 2012-04-13 23:17:23

+0

真棒,謝謝。我將ajax參數更改爲'async:false',並且工作正常。 – user 2012-04-19 04:17:31

1

的問題是,控制檯將更新對象的,如果他們得到更新,但不串的。

所以,如果你調用ajax調用函數將直接返回一個對象,但responseText將是未定義的,因爲調用還沒有完成。

所以,如果你想使用responseText你應該這樣做成功:

function print_XML(xml, s, jqXHR) { // there are 3 arguments past the third one is the same as the return of $.ajax 
    console.log("in printXML"); 
    console.log(xml); 

    $(xml).find("point").each(function() 
    { 
    var loaded_row = [ parseInt($(this).attr("number_protein_groups")), parseInt($(this).attr("log_likelihood")) ]; 
    console.log(loaded_row); 
    }); 

    console.log(jqXHR); 
    console.log(jqXHR.responseText); // now it works! 
}​ 
+0

這可能對他稍後有用,但他需要幫助的問題是與xml_ret.responseText奇怪的行爲。 – 2012-04-13 22:55:49

+0

micha,我的評論是在編輯之前添加的,當時你只是在談論解析響應。你的更新文本更多的是主題,我同意在成功調用中處理它是正確的,但我不確定它只是一個時間問題,因爲'console.log(xml_ret)'在*之前輸出正確的值*它不能在'xml_ret.responseText'上這樣做。 – 2012-04-13 23:14:06

+1

啊,在閱讀了user433831的回答之後,我看到了你所得到的。 +1給你們兩個;你先解釋它,但我認爲其他答案更清楚。 – 2012-04-13 23:17:20

0

responseText的出現在你的輸出xml_ret,因爲這是AJAX功能的jQuery是如何工作的。這是獲取回調返回

成功(數據,textStatus,jqXHR)

所以,當你試圖抓住xml_ret的屬性它失敗,因爲它僅僅是XML數據,而不是一個對象。第三個參數是你期望的,它也是稍微修改的,因爲它是一個jQuery的。

+1

這不是真的;根據文檔,jqXHR對象從AJAX調用中返回 - 您可以在上面包含的調試輸出中看到它。 – 2012-04-13 23:09:46

+0

啊是啊我的壞,在文檔的頂部太該死,我應該去睡覺:) – GillesC 2012-04-13 23:12:35