【问题标题】:Accessing a jQuery Closure function outside在外部访问 jQuery Closure 函数
【发布时间】:2013-01-19 07:09:13
【问题描述】:

我在我的文件中嵌入了这段代码,用于管理会话超时。这是来自http://www.fairwaytech.com/2012/01/handling-session-timeout-gracefully/

我想为所有 ajax 请求调用 SessionManager.extend() 完全的。所以我可以自动刷新我的会话管理器时间。

这是我试过的

<script type="text/javascript">
    $(document).ajaxSuccess(function (event, xhr, settings) {
        if (xhr.status === 200) {
            SessionManager().extend();
        }
    });
</script>

收到未找到 SessionManager 对象的错误。我们怎么称呼它?

以下是从该站点获取的库代码

$(function () { // Wrap it all in jQuery documentReady because we use jQuery UI Dialog
// HtmlHelpers Module
// Call by using HtmlHelpers.getQueryStringValue("myname");
var HtmlHelpers = function () {
    return {
        // Based on http://stackoverflow.com/questions/901115/get-query-string-values-in-javascript
        getQueryStringValue: function (name) {
            var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
            return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
        }
    };
} ();

// StringHelpers Module
// Call by using StringHelpers.padLeft("1", "000");
var StringHelpers = function () {
    return {
        // Pad string using padMask.  string '1' with padMask '000' will produce '001'.
        padLeft: function (string, padMask) {
            string = '' + string;
            return (padMask.substr(0, (padMask.length - string.length)) + string);
        }
    };
} ();

// SessionManager Module
var SessionManager = function () {
    // NOTE:  globalTimeoutPeriod is defined in _Layout.cshtml

    var sessionTimeoutSeconds = HtmlHelpers.getQueryStringValue('smt') || (globalTimeoutPeriod),
        countdownSeconds = HtmlHelpers.getQueryStringValue('smc') || 300,
        secondsBeforePrompt = sessionTimeoutSeconds - countdownSeconds,
        $dlg,
        displayCountdownIntervalId,
        promptToExtendSessionTimeoutId,
        originalTitle = document.title,
        count = countdownSeconds,
        extendSessionUrl = '/Session/Extend',
        expireSessionUrl = '/Session/Expire?returnUrl=' + location.pathname;

    var endSession = function () {
        $dlg.dialog('close');
        location.href = expireSessionUrl;
    };

    var displayCountdown = function () {
        var countdown = function () {
            var cd = new Date(count * 1000),
                minutes = cd.getUTCMinutes(),
                seconds = cd.getUTCSeconds(),
                minutesDisplay = minutes === 1 ? '1 minute ' : minutes === 0 ? '' : minutes + ' minutes ',
                secondsDisplay = seconds === 1 ? '1 second' : seconds + ' seconds',
                cdDisplay = minutesDisplay + secondsDisplay;

            document.title = 'Expire in ' +
                StringHelpers.padLeft(minutes, '00') + ':' +
                    StringHelpers.padLeft(seconds, '00');
            $('#sm-countdown').html(cdDisplay);
            if (count === 0) {
                document.title = 'Session Expired';
                endSession();
            }
            count--;
        };
        countdown();
        displayCountdownIntervalId = window.setInterval(countdown, 1000);
    };

    var promptToExtendSession = function () {
        $dlg = $('#sm-countdown-dialog')
            .dialog({
                title: 'Session Timeout Warning',
                height: 250,
                width: 350,
                bgiframe: true,
                modal: true,
                buttons: {
                    'Continue': function () {
                        $(this).dialog('close');
                        refreshSession();
                        document.title = originalTitle;
                    },
                    'Log Out': function () {
                        endSession(false);
                    }
                }
            });
        count = countdownSeconds;
        displayCountdown();
    };

    var refreshSession = function () {
        window.clearInterval(displayCountdownIntervalId);
        var img = new Image(1, 1);
        img.src = extendSessionUrl;
        window.clearTimeout(promptToExtendSessionTimeoutId);
        startSessionManager();
    };

    var startSessionManager = function () {
        promptToExtendSessionTimeoutId =
            window.setTimeout(promptToExtendSession, secondsBeforePrompt * 1000);
    };

    // Public Functions
    return {
        start: function () {
            startSessionManager();
        },

        extend: function () {
            refreshSession();
        }
    };
} ();

 SessionManager.start();
});

【问题讨论】:

  • 您必须更改其他代码才能显式导出该符号。
  • @Pointy,我按照现有的库代码尝试了这种方式,他们提到要公开公共以进行扩展。所以我添加了 return { GetSessionManager: function () { SessionManager(); }, };会话管理器.start();但不工作
  • 从 SessionManager 中移除 var 前缀
  • @Alex,真的很酷。我删除并调用了 SessionManager.extend(),它工作正常 :)

标签: javascript jquery jquery-ui closures


【解决方案1】:

从 SessionManager 中移除 var 前缀。

这里有一些关于范围的信息,http://msdn.microsoft.com/en-us/library/ie/bzt2dkta(v=vs.94).aspx

【讨论】:

  • 您的建议会在“严格”的 ES5 JavaScript 环境中引起问题。在这样的赋值中引用全局符号是错误的。最好将其更改为显式全局分配:window.SessionManager = ...
  • @Pointy,你是对的。除了在全局窗口范围内分配此 SessionManager 并检索之外,还有其他方法吗?类似于 SessionManager = function () 中的公共辅助方法,它使实例可以使用。
  • @Murali 编写代码的方式故意隐藏了 SessionManager 函数。完成这项工作的外部匿名函数不返回任何内容,但可以对其进行更改,使其返回对 SessionManager 的引用。
猜你喜欢
  • 1970-01-01
  • 2011-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多