AngularJS usa uma diretiva para impedir a execução de outras diretivas
-
26-12-2019 - |
Pergunta
Algumas ações em meu aplicativo Angular exigem que o usuário esteja registrado.Caso o usuário não esteja cadastrado queremos mostrar um “Registrar modal” e evitar a ação original.
Essas ações podem ser acionadas via ng-click ou qualquer outra diretiva de "vinculação de clique" (por exemplo, a 'modal-toggle').
Então encontrei esta solução: https://stackoverflow.com/a/16211108/2719044
Isso é muito legal, mas só funciona com ng-click.
Primeiro eu queria tornar dinâmica a propriedade "terminal" da diretiva, mas não consegui.
Portanto, a ideia era definir "terminal" como verdadeiro e impedir manualmente a ação de clique padrão na diretiva.
Aqui está meu DOM
<!-- 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>
E minhas diretivas (que não funcionam...)
// 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();
}
});
}
};
});
...E é por isso que estou aqui.Qualquer ideia ?
Muito obrigado.
Solução
Você estava extremamente próximo.Em vez de stopPropagation você precisava pararImediatoPropagação.A diferença entre os dois está resumida em esta resposta do StackOverflow por @Dave:
stopPropagation
impedirá qualquer pai manipuladores de serem executados enquantostopImmediatePropagation
fará o mesmo mas também impedir que outros manipuladores sejam executados.
Então, para corrigir o código, tudo o que precisamos fazer é trocar esse método e Voilà:
app.directive('userNeeded', function() {
return {
priority: -100
restrict: 'A',
link: function(scope, element, attrs) {
element.bind('click', function(e) {
if(!isRegistered()) {
e.stopImmediatePropagation();
}
});
}
};
});
Aqui está um exemplo Plunker do código de trabalho.No exemplo, modifiquei ligeiramente a diretiva para permitir que eventos específicos fossem especificados (como user-needed="submit"
) passando o valor diretamente para o element.bind
função;no entanto, o padrão é 'clique'.