Подтвердить что ты не робот

Перехват ng-click в angularJS

Можно ли написать перехватчик для ng-click? У меня есть кнопка или ссылка, которая приводит к удалению объекта в бэкэнд. Я хотел бы иметь диалог подтверждения (модальный), просто добавив атрибут к кнопке/ссылке. Например:.

<a href="#" ng-click="deleteIt(id)" confirmation-needed>Delete</a>

Возможно ли это с помощью AngularJS? Есть ли лучший способ решить эту проблему?

EDIT Метод deleteIt находится в разных контроллерах.

спасибо

4b9b3361

Ответ 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>