如何将回调函数从全局命名空间发送到命名空间(范围问题)

发布于 2024-12-29 12:34:00 字数 3369 浏览 2 评论 0原文

我有一个全局函数,它将 post 请求发送到我的 api,如下所示,

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));

,但我总是收到一个错误,提示 window[callback] 函数未定义。另外,我不能只是将命名空间之外的函数粘贴到全局区域中,因为重点是保持每个页面的 JS 模块化。

I have a global function that sends post requests to my api it looks like the following,

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;                
}

This worked ok until I put my page specific javascript for pages in a jquery name space, based off of the model found here http://jacob4u2.posterous.com/documentready-with-jquery-mobile. I have a login page and the attached JS is as follows

(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));

but i always get an error that the window[callback] function is undefined. ALso I can't just stick the function outside of the namespace into a global area because the whole point is to keep the JS modularized per page.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

纵山崖 2025-01-05 12:34:00

正如您可能看到的,您收到此错误是因为您的回调不存在于 window 对象的范围内。

尝试更新您的 sendRequest 函数以调用回调,如下所示:

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

这样做是确保 callback 的值是一个函数并调用回调,设置回调的执行与窗口的执行相同,并传递 d.data 作为回调的参数。

正如 JAAulde 指出的那样,您可能不想在 window 范围内执行回调,并且您可能根本不想更改其执行范围。在这种情况下,这将执行以下操作:

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

As you probably can see, you are receiving this error because your callback does not exist in the scope of the window object.

Try updating your sendRequest function to invoke the callback as follows:

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

Whit this will do is make sure that the value of callback is a function and invoke the callback, setting the scope of the callback's execution to that of the window and passing d.data as the callback's argument.

As JAAulde pointed out, you may not want to execute the callback in the scope of window, and you may not want to change it's scope of execution at all. In that case, this will do:

if ($.isFunction(callback)) {
    callback(d.data);
}     
偏爱你一生 2025-01-05 12:34:00

语法 window[callback]() 期望 callback 是一个字符串,表示窗口范围内的函数名称。您正在传递一个函数 (test) 而不是字符串,并且该函数未在窗口范围中定义。

解决此问题的一种方法是编辑 sendRequest 函数以更改:

window[callback](cacheObject);

To:

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

And:

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);
    }
}

这些编辑将允许函数直接作为回调传递,并且将避免破坏当前正在传递字符串的现有代码区域。

The syntax, window[callback]() expects for callback to be a string representing the name of a function which lives in the window scope. You are passing a function (test) instead of a string, and that function is not defined in the window scope.

One method of fixing this would be to edit your sendRequest function so as to change:

window[callback](cacheObject);

To:

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

And:

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);
    }
}

These edits will allow functions to be passed directly as the callback, and will avoid breaking existing areas of code where you're currently passing a string.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文