拦截angularJS中的ng-click

时间:2013-04-25 07:34:29

标签: angularjs

是否有可能为ng-click写一个拦截器? 我有一个按钮或链接,导致删除后端中的对象。我想通过向按钮/链接添加属性来确认对话框(模态)。 E.g:

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

AngularJS可以实现吗?有没有更好的方法可以解决这个问题?

编辑 deleteIt方法驻留在不同的控制器中。

THX

4 个答案:

答案 0 :(得分:50)

我在下面放了一个示例指令:

http://plnkr.co/edit/GJwK7ldGa9LY90bMuOfl?p=preview

我通过创建指令来实现它:

  1. priority高于ngClick,以便在ngClick之前调用,
  2. 制作terminal,以便它不会调用ngClick
  3. 收听点击事件,然后在邮件正常时评估ngClick值。
  4. 作为奖励,您可以传递自己的信息,例如:

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

    希望有所帮助。

答案 1 :(得分:10)

我已经放弃了让皮兰的工作回答,正如我所希望的那样。相反,我已经开始用我自己的指令替换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如何实现可以改善这一点,但我还没有完成它!

答案 2 :(得分:5)

我玩了很长时间,但是Angular的异步特性使得很难指望每个指令一起玩得很好。然后,我看到@ tosh的回答,让我思考。

我认为这结合了几个优点:创建指令并预先点击

因此,只需将此指令添加到您的应用中,然后添加&#34;确认 - 点击&#34;属性链接,以及ngClick的confirmClick()函数。

链接:

<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()对话框非常相似,但是因为你在指令中有它,你可以自定义如何选择运行确认对话框(可能是一个漂亮的模态,而不是窗口对话框)。 / p>

**** BONUS ANSWER ****

我更多地玩这个并集成了一个解决方案,它使用模态窗口作为确认,而不是默认窗口。这是完整的解决方案:https://stackoverflow.com/a/23718694/1135826

答案 3 :(得分:3)

您可以将$window注入您的控制器,以便您可以使用$window.confirm 你的范围,然后:

<a href="#" ng-click="confirm('message') && deleteIt(id)">Delete</a>