2011-08-19 26 views
0

標題是一個猜測,什麼是我的腳本錯誤會:全局範圍的問題,返回值和ajax?

這是我global.js腳本:

alert(search.getLabelsNames(); //alerts as undefined. 
$('#search').autocomplete({ 
    source: function(request) { 
     search.getLabelsNames(); 
    }, 
    minLength:1 
}); 

這是我functions.js腳本:

var search; 
window.search = { 
    getLabelsNames:function(search) { 
     $.ajax({ 
      url : '../db_scripts/get_labels_names.php', 
      type: "POST", 
      data: { id: search }, //this defaults to nothing. not a problem 
      success : function(data) { 
       var dataObj = jQuery.parseJSON(data); 
       $.each(dataObj, function() { 
        alert(this.name); 
        return this.name; 
       }) 
      } 
     }); 
    } 
} 

在每個函數this.name都會從數據庫中正確返回每個標籤名稱。但是當我從globals.js調用它時,它將返回爲undefined。如果我返回數字1,search.getLabelsNames()警報1 ..所以找到全局函數沒有問題。

這個腳本有什麼問題,爲什麼不能global.js找到正在返回的this.name

回答

3

你有兩個問題:

  1. 不能從jQuery.each回調返回數據。返回值指示是否停止迭代。從documentation

    通過使回調函數返回false,我們可以在特定的迭代中打破$.each()循環。返回非錯誤與for循環中的continue語句相同;它會立即跳到下一個迭代。

  2. 您無法從Ajax回調中返回數據。阿賈克斯是異步,這意味着在你的情況下,getLabelsNames返回之前響應檢索和處理。

幸運的是,自動完成插件接受函數作爲源。您已經在使用它,但不正確。讓它接受第二個參數,這是一個回調。從documentation

第三個變體,回調提供了最大的靈活性,並可用於將任何數據源連接到自動完成。回調得到兩個參數

  • 的請求對象,與所謂的「術語」一個單一的財產,這是指當前值在文本輸入。例如,當用戶在城市字段中輸入「新喲」時,自動完成詞將等於「新喲」。

  • 響應回調,它需要一個參數來包含要提示給用戶的數據。這些數據應根據提供的術語進行過濾,並且可以採用上述任何用於簡單本地數據(String-Array或帶有標籤/值/兩個屬性的對象數組)的格式。提供自定義源回調以在請求期間處理錯誤時,這很重要。即使遇到錯誤,您也必須始終調用響應回調。這可確保小部件始終具有正確的狀態。

那麼,你有你所要做的就是通過一起getLabelsNames,以便它可以在Ajax調用的success方法來調用這個回調:

$('#search').autocomplete({ 
    source: function(request, callback) { 
     // pass the callback along 
     search.getLabelsNames(request.term, callback); 
    }, 
    minLength:1 
}); 

window.search = { 
    getLabelsNames:function(search, callback) { // accept callback as argument 
     $.ajax({ 
      url : '../db_scripts/get_labels_names.php', 
      type: "POST", 
      data: { id: search }, //this defaults to nothing. not a problem 
      success : function(data) { 
       // format the data 
       data = $.map(jQuery.parseJSON(data), function(obj) { 
        return obj.name; 
       }); 
       // pass the data to the callback 
       callback(data); 
      } 
     }); 
    } 
} 

請注意,我用jQuery.map[docs]這裏,返回值的形式回調有不同的含義。不要將它與jQuery.each混淆。

+0

它的工作!你的第二個編輯工作!非常感謝你的解答和解釋。現在我必須閱讀'$ .map'是什麼。 – Phil

+0

@菲爾:不客氣:)基本上'映射'是循環一組項目並提取某些數據的另一種方式。你可以用'for'循環做同樣的事情,並在數組中添加每個'obj.name'。但是,是的,閱讀它:) –

+0

但只是爲了確保'callback(data)'是什麼是「返回」到'autocomplete()'函數?所以在將來,我想要做的是格式化數據並將其傳遞給每次回調?我想我明白了 – Phil

0

this取決於調用的上下文。所以在你的內心功能上,this是不一樣的。

根據您的dataObj是如何組織的,你可能想要做的事,如:

$.each(dataObj, function(key, value) { 
       alert(value.name); // value will correspond to the current item being looped over 
       return value.name; 
      }) 
+0

好的,我該如何解決這個問題? – Phil

+0

@Phil:查看我的更新。這是一個例子。 – Mrchief

+0

即使'getLabelsNames()'中的alert()正在顯示正確的值,它仍然返回「undefined」 – Phil

0

AJAX調用是異步的,這意味着你解僱他們,他們稍後回覆。您不能簡單地從ajax調用中「返回」一個值 - 您需要將值傳遞給另一個「成功」函數。

+0

你能舉個例子說說你在說什麼嗎?我應該在'.each'循環中創建一個字符串並將其傳遞給一個返回它的函數? – Phil

+0

而不是「return this.name;」你可能想要做一些類似「setLabelsNames(this.name)」的東西,它會將你的值賦給你正在使用的數組,對象或變量。你需要編寫「setLabelsNames」函數。 –