Перехват ng-click в angularJS
Можно ли написать перехватчик для ng-click?
У меня есть кнопка или ссылка, которая приводит к удалению объекта в бэкэнд. Я хотел бы иметь диалог подтверждения (модальный), просто добавив атрибут к кнопке/ссылке. Например:.
<a href="#" ng-click="deleteIt(id)" confirmation-needed>Delete</a>
Возможно ли это с помощью AngularJS? Есть ли лучший способ решить эту проблему?
EDIT Метод deleteIt находится в разных контроллерах.
спасибо
Ответы
Ответ 1
Я поставил примерную директиву в:
http://plnkr.co/edit/GJwK7ldGa9LY90bMuOfl?p=preview
Я достигаю этого, создавая директиву:
- с более высоким
priority
чем ngClick
, так что он вызывается до ngClick
,
- делает
terminal
так, чтобы он не вызывал ngClick
.
- прослушивание событий кликов, а затем оценка значения
ngClick
, если сообщение в порядке.
В качестве бонуса вы можете передать свое собственное сообщение, например:
<a href="#" ng-click="deleteIt(id)"
confirmation-needed="Really Delete?"
>Delete with custom message</a>
Код выглядит следующим образом:
app.directive('confirmationNeeded', function () {
return {
priority: 1,
terminal: true,
link: function (scope, element, attr) {
var msg = attr.confirmationNeeded || "Are you sure?";
var clickAction = attr.ngClick;
element.bind('click',function () {
if ( window.confirm(msg) ) {
scope.$eval(clickAction)
}
});
}
};
});
Надеюсь, что это поможет.
Ответ 2
Я отказался от ответа Пирана на работу, как мне бы хотелось. Вместо этого я начал просто заменять ngClick своей собственной директивой:
.directive('confirmClick', function() {
return {
restrict: 'A',
link: function(scope, elt, attrs) {
elt.bind('click', function(e) {
var message = attrs.confirmation || "Are you sure you want to do that?";
if (window.confirm(message)) {
var action = attrs.confirmClick;
if (action)
scope.$apply(scope.$eval(action));
}
});
},
};
})
Эта директива даже не имеет собственной области видимости, что значительно упрощает ее объединение с другими директивами. Он берет все, что нужно непосредственно от attrs
. Он используется так:
<span ng-show="editing" confirm-click="delete()" confirmation="delete confirmation message goes here">some text</span>
Функция delete()
должна существовать где-то выше в цепочке $scope
. Я уверен, что это может быть улучшено, если поближе познакомиться с тем, как ng-click
реализовано, но я еще не добрался до него!
Ответ 3
Я играл с этим в течение долгого времени, но асинхронный характер Angular затрудняет учет каждой директивы, играющей красиво вместе. Затем я увидел @tosh ответ, который заставил меня думать.
Я думаю, что это сочетает в себе несколько преимуществ: Создать директиву и Prepend ngClick
Итак, просто добавьте эту директиву в свое приложение, а затем добавьте к своей ссылке атрибут "подтвердить щелчок", а также функцию confirmClick() для вашего ngClick.
Ссылка:
<a href="#" ng-click="confirmClick() && deleteIt(id)" confirm-click>Delete</a>
Директива
.directive('confirmClick', function() {
return {
link: function (scope, element, attrs) {
// setup a confirmation action on the scope
scope.confirmClick = function(msg) {
// msg can be passed directly to confirmClick('are you sure?') in ng-click
// or through the confirm-click attribute on the <a confirm-click="Are you sure?"></a>
msg = msg || attrs.confirmClick || 'Are you sure?';
// return true/false to continue/stop the ng-click
return confirm(msg);
}
}
}
})
Это очень похоже на ввод стандартного диалога confirm(), но поскольку вы указали его в директиве, вы можете настроить, как вы решили запустить диалоговое окно подтверждения (возможно, довольно модальное, а не диалоговое окно окна).
**** БОНУС ОТВЕТ ****
Я играл с этим больше и интегрировал решение, которое использует модальное окно в качестве подтверждения, а не окно по умолчанию. Здесь полное решение: fooobar.com/questions/261396/...
Ответ 4
Вы можете ввести $window
в свой контроллер, чтобы вы могли использовать $window.confirm
из
ваш объем, затем:
<a href="#" ng-click="confirm('message') && deleteIt(id)">Delete</a>