2012-01-25 1 views
1

У меня есть глобальная функция, которая отправляет почтовые запросы к моему апи это выглядит следующим образом,Как я могу отправить функцию обратного вызова из глобального пространства имен для имени пространства (ОБЪЕМ выпуск)

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 функцию, чтобы вызвать функцию обратного вызова следующим образом:

if ($.isFunction(callback)) { 
    callback.call(window, d.data); 
} 

йота это будет сделать, это убедиться, что значение callback является функцией и вызовите функцию обратного вызова, установив рамки выполнения функции обратного вызова в к окну и передаче d.data в качестве аргумента обратного вызова.

Как указал JAAulde, вы можете не захотеть выполнить обратный вызов в области window, и вы можете не захотеть полностью изменить его область выполнения. В этом случае это будет делать:

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

Вы не знаете наверняка, что обратный вызов должен выполняться в рамках «окна». – JAAulde

+0

@JAAulde - это правда. Я обновил свой ответ соответствующим образом. – RoccoC5

+0

Это прекрасно работает, спасибо за помощь! – Brian

2

Синтаксис, window[callback]() ожидает callback быть строка, представляющая имя функции, которая живет в окне рамки. Вы передаете функцию (test) вместо строки, и эта функция не определена в области окна.

Один из способов фиксации этого было бы изменить sendRequest функцию так, чтобы изменить:

window[callback](cacheObject); 

To:

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

И:

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

To:

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

Эти изменения позволят функции должны быть переданы непосредственно в качестве обратного вызова, и позволит избежать нарушений существующих областей коды, где вы в данный момент передачи строки.

+0

Это определенно проблема, спасибо за вклад. – Brian