【问题标题】:AngularJS: How to chain $timeout inside $watchAngularJS:如何在 $watch 中链接 $timeout
【发布时间】:2014-01-24 06:58:55
【问题描述】:

我试图在 $watch 中链接两个 $timeout 方法。 $watch 用于查看用户是否执行了任何操作。如果是,那么我将取消两个 $timeout 实例。这是代码sn-p。

.run(['$rootScope',  '$location', '$timeout', 'applicationCache', function ($rootScope, $location, $timeout, applicationCache) {
var popupTimer, logoutTimer;
var logoutInterval = 10000, popupInterval = 5000;
$rootScope.$watch(function detectIdle() {
    if($rootScope.userLoggedIn){
        (popupTimer) ? $timeout.cancel(popupTimer) : undefined; // check if timer running, cancel it
        (logoutTimer) ? $timeout.cancel(logoutTimer) : undefined; // check if other timer running, cancel it
        popupTimer = $timeout(function(){
                console.log("show popup");
                logoutTimer = $timeout(function(){
                    console.log("logout");
                    $rootScope.userLoggedIn = false; // set logged In status to false
                    applicationCache.removeAll(); // destroy all session storage
                    $location.path("/login");
                },logoutInterval);
            },popupInterval);
    }
});
}])

我想要实现的是在空闲状态下,5 秒后向用户显示他/她的会话即将到期的弹出窗口。如果没有交互,他会在 10 秒后退出。如果他交互取消计时器并重新初始化弹出计时器。

我面临的问题是,如果根本不执行交互,则内部超时不会执行。它在初始化后立即被取消。在控制台中永远不会打印“注销”。我在控制台中看到的唯一内容是“显示弹出窗口”被重复打印。

我猜 $watch 会在第二个计时器初始化后立即执行,从而取消内部计时器。

可以做些什么来处理这个问题?

【问题讨论】:

    标签: javascript angularjs timeout watch


    【解决方案1】:

    我会使用一些布尔变量。请参阅 isInProgress

    .run(['$rootScope',  '$location', '$timeout', 'applicationCache', function ($rootScope, $location, $timeout, applicationCache) {
    var popupTimer, logoutTimer, isInProgress= false;
    var logoutInterval = 10000, popupInterval = 5000;
    $rootScope.$watch(function detectIdle() {
        if($rootScope.userLoggedIn && !isInProgress){
            (popupTimer) ? $timeout.cancel(popupTimer) : undefined; // check if timer running, cancel it
            (logoutTimer) ? $timeout.cancel(logoutTimer) : undefined; // check if other timer running, cancel it
            popupTimer = $timeout(function(){
                    console.log("show popup");
                    logoutTimer = $timeout(function(){
                        isInProgress = false;
                        console.log("logout");
                        $rootScope.userLoggedIn = false; // set logged In status to false
                        applicationCache.removeAll(); // destroy all session storage
                        $location.path("/login");
                    },logoutInterval);
                },popupInterval);
        }
        isInProgress = true;
    });
    }])
    

    【讨论】:

    • 感谢您的回复。但是这种方法的问题是,一旦“isInProgress”设置为“false”,如果用户在弹出窗口上执行一些操作,两个计时器都不会被取消。他仍将被注销。此外,设置“isInProgress=true”将使 if 条件永远失败。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-11
    • 2016-09-11
    • 2014-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多