Предотвратить событие по умолчанию и возобновить его после

Я хочу создать директиву angularjs для ограниченных действий на моем веб-сайте. Например, у меня есть привязка, которая запускает изменение маршрута в angular, но перед этим я хочу показать модальный диалог входа в систему.

Я могу остановить маршрутизацию с помощью 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');
                }
            });
        }
    }
}]);

Любое предложение?


person user1387219    schedule 01.10.2014    source источник


Ответы (2)


Я нашел следующее решение:

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

Это не возобновление ... что буквально я считаю невозможным. Решение основано на этом вопросе.

person user1387219    schedule 02.10.2014

Я не думаю, что Event.preventDefault() будет фиксировать или задерживать события. AFAIK, он только отменяет их полностью (см. MDN) . Я не верю, что есть способ возобновить исходное событие с его обработчиком (-ами) в такт. (Но, возможно, вы не собираетесь понимать термин «резюме» так буквально.)

В этом конкретном случае, я думаю, вам придется изучить $(e.target).attr('href'), а позже ** использовать его для обновления маршрута (вам нужно будет внедрить службу $location (Docs) и используйте его .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));
    });
  }));
});

Вы должны настроить свой .isAuthenticated() метод для запуска обратного вызова, когда пользователь действительно аутентифицирован.

person Jeff McMahan    schedule 01.10.2014