2012-01-25 55 views
1

我發送POST請求我的API,它看起來像下面這樣一個全球性的功能,如何發送一個回調函數從一個全局命名空間的命名空間(SCOPE問題)

function sendRequest(method,params,callback,cache,override){ 

    var cacheObject = null; 

    if(override == true){ 
     window.localStorage.removeItem(method); 
    } 
    //check if cache exists 
    if(cache == true){ 

     console.log('attempting to find cache'); 

     var cacheString = window.localStorage.getItem(method); 

     if(cacheString){ 
      //put back into object and return to callback 
      cacheObject = JSON.parse(cacheString); 

      if(cacheObject){ 
       console.log('cache found' + cacheString); 
      } 

      window[callback](cacheObject); 
      return true; 
     } 
    } 
    if(cacheObject == null || override == true){ 

     console.log('sending new request'); 

     var apiKey = ""; 
     var sessionKey = null; 
     sessionKey = window.localStorage.getItem("session_key"); 

     var params2 = { 
      api_key: apiKey, 
      session_key: sessionKey 
     } 

     var object = $.extend({}, params,params2);  

     var url = apiUrl+method; 
     var p = jQuery.param(object); 

     // console.log(url); 
     // console.log(p); 

     $.mobile.showPageLoadingMsg();  
     $.post(apiUrl+method,p,function(d) { 

      $.mobile.hidePageLoadingMsg(); 
      //  console.log(d.success); 
      //  console.log(d.message); 

      var obj2 = d.data; 
      var dataString = JSON.stringify(obj2); 

      if(cache == true){ 

       console.log('updating cache'); 

       window.localStorage.removeItem(method); 

       window.localStorage.setItem(method,dataString); 
      } 

      console.log(dataString); 

      if(d.success == true){ 
       window[callback](d.data); 
      } 
      else{ 
       if(d.message != null){ 
        alert(d.message); 
       } 
      } 
     },'json') 
     .error(function(xhr) { 

      console.log(xhr.status); 
      var status = xhr.status; 
      $.mobile.hidePageLoadingMsg(); 

      if(status == 400){ 
       window.localStorage.clear(); 
       location.href='index.html'; 

      } 
     }); 

     return true; 
    } 
    return false;     
} 

該工作確定直到我把我的頁面特定的JavaScript頁面在jquery名字空間中,基於這裏發現的模型http://jacob4u2.posterous.com/documentready-with-jquery-mobile。我有一個登錄頁面和附加JS是如下

(function($, ns) { 
    function loginPage() { 
    }; 

    loginPage.prototype.init = function($page, pageDom) { 

     $('#login_button').click(function() { 
      var params = { 
        email : $('#email').val(), 
        password : $('#password').val() 

       } 

      //test is the callback function that should fire via window[callback] 
      sendRequest('login',params,test); 

     }); 

    }; 

    ns.pages = ns.pages || {}; 
    ns.pages.login = new loginPage(); 

    function test(){ 
     alert('callback successful'); 
    } 
}(jQuery, MYAPP)); 

但我總是得到一個錯誤,該窗口[回調]功能是不確定的。另外,我不能將名稱空間之外的函數粘貼到全局區域中,因爲整個問題的目的是爲了保持每個頁面的JS模塊化。

回答

2

正如您可能會看到的那樣,您收到此錯誤是因爲您的回調不存在於window對象的範圍內。

嘗試更新sendRequest函數調用回調如下:

​​

聖靈降臨節,這將要做的是確保的callback值是一個函數,調用回調函數,設置回調的執行範圍作爲回調的參數傳遞給窗口的d.data。

正如JAAulde指出的那樣,您可能不想在window範圍內執行回調,您可能根本不想改變它的執行範圍。在這種情況下,這將做到:

if ($.isFunction(callback)) { 
    callback(d.data); 
}  
+0

您不確定回調應該在'window'範圍內運行。 – JAAulde

+0

@JAAulde - 這是真的。我已經適當地更新了我的答案。 – RoccoC5

+0

這工作完美,感謝您的幫助! – Brian

2

的語法,window[callback]()預計,callback是代表其生活在窗口範圍函數的名稱的字符串。您正在傳遞函數(test)而不是字符串,並且該函數未在窗口範圍中定義。

固定,這將是編輯您的sendRequest功能,從而改變的一種方法:

window[callback](cacheObject); 

要:

if(typeof callback === 'function'){ 
    callback(cacheObject); 
} 
else if(typeof callback === 'string'){ 
    window[callback](cacheObject); 
} 

和:

if(d.success == true){ 
    window[callback](d.data); 
} 

要:

if(d.success == true){ 
    if(typeof callback === 'function'){ 
     callback(d.data); 
    } 
    else if(typeof callback === 'string'){ 
     window[callback](d.data); 
    } 
} 

這些修改將允許函數直接傳遞的回調,並避免破壞的代碼存在這些區域中,目前正在傳遞一個字符串。

+0

這絕對是一個問題,感謝您的意見。 – Brian