防止发生默认事件,然后再恢复

问题描述 投票:1回答:2

我想为我的网站的受限操作创建一个angularjs指令。例如,我有一个锚,它将触发角度的路线更改,但在此之前,我想显示一个模式登录对话框。

我可以使用preventDefault停止路由,但是无法恢复路由。我还尝试了虚拟事件触发(element.triggerHandler('click')),但未成功。

我不仅要将该指令应用于路由更改,还希望将其应用于任何其他操作。

.directive('loginRequired', ['AuthService', 'AUTH_EVENTS',
function(AuthService, AUTH_EVENTS) {
    return {
        link : function(scope, element, attrs) {
            element.on('click', function(e) {
                if (!AuthService.isAuthenticated()) {
                    e.preventDefault();
                    $('#myModal').modal();
                    scope.$on(AUTH_EVENTS.loginSuccess, function() {
                        //resume event
                    });
                    console.log('$scope.$on happened');
                }
            });
        }
    }
}]);

有任何建议吗?

jquery angularjs angularjs-directive jquery-events
2个回答
1
投票

我找到的解决方案是:

.value('lastPrevented', {
    elem : null
}).directive('loginRequired', ['AuthService', 'lastPrevented',
function(AuthService, lastPrevented) {
    return {
        link : function(scope, element, attrs) {
            element.on('click', function(e) {
                if (!AuthService.isAuthenticated()) {
                    lastPrevented.elem = element;
                    e.preventDefault();
                    $('#myModalLogin').modal();
                }
            });
        }
    }
}]).run(['lastPrevented', '$rootScope', 'AUTH_EVENTS', '$timeout',
function(lastPrevented, $rootScope, AUTH_EVENTS, $timeout) {
    $rootScope.$on(AUTH_EVENTS.loginSuccess, function() {
        $timeout(function() {
            if (!!lastPrevented.elem) {
                lastPrevented.elem[0].click();
                lastPrevented.elem = null;
            }
        })
    });
}]);

这不是恢复...从字面上看,我认为这是不可行的。该解决方案的灵感来自this question


0
投票

我认为Event.preventDefault()不会捕获或延迟事件。 AFAIK,只会完全取消它们(请参见MDN)。我不认为有一种方法可以在处理程序完好无损的情况下恢复原始事件。 (但也许您不打算将“恢复”一词用字面意思理解。)

[在这种情况下,我认为您必须检查$(e.target).attr('href'),以后**用它来更新路由(您需要注入$location服务(Docs)并使用其[ C0] getter / setter方法。

-祝你好运!


**快速说明:您很可能希望将“简历”处理程序作为回调传递给.path()方法,因为它可能会等待某种异步业务。粗略的例子:

AuthService.isAuthenticated()

您将设置element.on('click', function(e) { e.preventDefault(); newRoute = $(e.target).attr('href'); AuthService.isAuthenticated(function () { $('#myModal').modal(); scope.$on(AUTH_EVENTS.loginSuccess, function() { $location.path(getWhatYouNeedFromUrlString(newRoute)); }); })); }); 方法以在确实通过用户身份验证时触发回调。

© www.soinside.com 2019 - 2024. All rights reserved.