AngularJS использует директиву для предотвращения выполнения других директив

Некоторые действия в моем приложении Angular требуют регистрации пользователя. Если пользователь не зарегистрирован, мы хотим показать модальное окно «Регистрация» и предотвратить исходное действие.

Эти действия могут быть запущены с помощью ng-click или любой другой директивы «связывания кликов» (например, «modal-toggle»).

Итак, я нашел это решение: https://stackoverflow.com/a/16211108/2719044

Это довольно круто, но работает только с ng-click.

Сначала я хотел сделать свойство "терминал" директивы динамическим, но не смог этого сделать.

Итак, идея заключалась в том, чтобы установить для «терминала» значение true и вручную предотвратить действие щелчка по умолчанию в директиве.

Вот мой ДОМ

<!-- This can work with terminal:true and scope.$eval(attrs.ngClick) (see example above) -->
<div user-needed ng-click="myAction()">Do it !</div> 

<!-- This doesn't work. I can't manage to prevent the modal-toggle to be executed -->
<div user-needed modal-toggle="my-modal-id-yey">Show yourself modal !</div> 

И моя директива (ы) (которые не работают...)

// First try (with terminal:true)
app.directive('userNeeded', function() {
    return {
        priority: -100,
        terminal: true,
        restrict: 'A',
        link: function(scope, element, attrs) {
            element.bind('click', function(e) {
                if(isRegistered()) {
                    // Here we do the action like scope.$eval or something
                }
            });
        }
    };
});

// Second try (with stopPropagation)
app.directive('userNeeded', function() {
    return {
        priority: -100
        restrict: 'A',
        link: function(scope, element, attrs) {
            element.bind('click', function(e) {
                if(!isRegistered()) {
                    e.stopPropagation();
                }
            });
        }
    };
});

...И именно поэтому я здесь. Любая идея ?

Большое спасибо.


person Maslow    schedule 14.04.2014    source источник
comment
вам следует взглянуть на проект angular-app, который обрабатывает аутентификацию наилучшим образом, который я нашел с этого момента: github.com/angular-app/angular-app (см. модуль безопасности)   -  person Jscti    schedule 14.04.2014
comment
Это, похоже, не решает мою проблему. Мне не нужна общая функция аутентификации.   -  person Maslow    schedule 15.04.2014
comment
это не. вы можете выбирать маршрут за маршрутом, если хотите ограничить доступ (см. узел resolve при определении нового маршрута). И это ограничение может быть обычным пользователем/администратором.. Но вам не обязательно перенимать их шаблон ;) это просто очень хороший пример того, что можно сделать.   -  person Jscti    schedule 15.04.2014
comment
Другое дело, что способ, которым вы хотите ограничить свои страницы событиями onclick, не может быть безопасным. Вам нужно защитить не ссылки, а маршрут   -  person Jscti    schedule 15.04.2014
comment
Все мои действия не маршруты. Иногда речь идет только о том, чтобы показать или не модальное окно. И да, это не может быть безопасно, но в моем случае это не важно. Форма в модальном окне уже защищена, но действие по показу модального окна не обязательно. Я просто хочу поймать щелчок и проверить с помощью директивы, аутентифицирован ли пользователь. Если нет, я не показываю модальное окно и перенаправляю на форму входа. Не знаю, ясно ли мне.   -  person Maslow    schedule 15.04.2014
comment
извините за поздний ответ, но я столкнулся с аналогичной проблемой (как в вашем заголовке), я решил конкретную проблему, с которой вы столкнулись, используя пользовательскую директиву ng-permission, которая скрывает элемент, если у пользователя нет разрешения на это действие.   -  person harishr    schedule 19.12.2014
comment
Я не уверен, что понимаю вопрос. Не могли бы вы ответить на несколько вопросов? Насколько я понимаю, вы хотите, чтобы ‹div first.one›‹/div› показывал, если пользователь не зарегистрирован, и отображал ‹div second.one›‹/div›, если пользователь зарегистрирован, или наоборот. Это правда?   -  person SoEzPz    schedule 06.01.2015


Ответы (1)


Вы были очень близки. Вместо stopPropagation вам нужно остановитьнемедленноераспространение. Разница между ними кратко изложена в этом ответе StackOverflow от @Dave:

stopPropagation предотвратит выполнение любых родительских обработчиков, а stopImmediatePropagation сделает то же самое, но также предотвратит выполнение других обработчиков.

Итак, чтобы исправить код, все, что нам нужно сделать, это поменять местами этот метод и вуаля:

app.directive('userNeeded', function() {
    return {
        priority: -100
        restrict: 'A',
        link: function(scope, element, attrs) {
            element.bind('click', function(e) {
                if(!isRegistered()) {
                    e.stopImmediatePropagation();
                }
            });
        }
    };
});

Вот пример Plunker рабочего кода. В этом примере я немного изменил директиву, чтобы разрешить указывать определенные события (например, user-needed="submit"), передавая значение непосредственно в функцию element.bind; однако по умолчанию используется «щелчок».

person Jonathan Gawrych    schedule 13.02.2016