ng-click上的确认对话框 - AngularJS

时间:2013-08-19 12:15:09

标签: javascript angularjs angularjs-directive angularjs-scope

我正在尝试使用自定义angularjs指令在ng-click上设置确认对话框:

app.directive('ngConfirmClick', [
    function(){
        return {
            priority: 1,
            terminal: true,
            link: function (scope, element, attr) {
                var msg = attr.ngConfirmClick || "Are you sure?";
                var clickAction = attr.ngClick;
                element.bind('click',function (event) {
                    if ( window.confirm(msg) ) {
                        scope.$eval(clickAction)
                    }
                });
            }
        };
}])

这很有效,但不幸的是,使用my指令的标记内的表达式不会被评估:

<button ng-click="sayHi()" ng-confirm-click="Would you like to say hi?">Say hi to {{ name }}</button>

(在这种情况下不评估名称)。这似乎是由于我的指令的终端参数。你对解决方法有什么想法吗?

测试我的代码: http://plnkr.co/edit/EHmRpfwsgSfEFVMgRLgj?p=preview

17 个答案:

答案 0 :(得分:90)

如果您不介意不使用ng-click,则可以正常使用。您可以将其重命名为其他内容并仍然读取该属性,同时避免点击处理程序被触发两次问题。

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

我认为问题是terminal指示其他指令不运行。与{{ }}的数据绑定只是ng-bind指令的别名,可能会被terminal取消。

答案 1 :(得分:56)

一种干净的指令方法。

更新:旧答案(2014)

它基本上拦截ng-click事件,显示ng-confirm-click="message"指令中包含的消息并要求用户确认。如果单击确认,则执行正常ng-click,否则脚本将终止并且ng-click未运行。

<!-- index.html -->
<button ng-click="publish()" ng-confirm-click="You are about to overwrite your PUBLISHED content!! Are you SURE you want to publish?">
  Publish
</button>
// /app/directives/ng-confirm-click.js
Directives.directive('ngConfirmClick', [
  function(){
    return {
      priority: -1,
      restrict: 'A',
      link: function(scope, element, attrs){
        element.bind('click', function(e){
          var message = attrs.ngConfirmClick;
          // confirm() requires jQuery
          if(message && !confirm(message)){
            e.stopImmediatePropagation();
            e.preventDefault();
          }
        });
      }
    }
  }
]);

Zach Snow的代码信用:http://zachsnow.com/#!/blog/2013/confirming-ng-click/

更新:新答案(2016)

1)将前缀从'ng'更改为'mw',因为前者('ng')是为原生角度指令保留的。

2)修改指令以传递函数和消息,而不是拦截ng-click事件。

3)添加默认“你确定吗?”如果未向mw-confirm-click-message =“”提供自定义消息,则显示消息。

<!-- index.html -->
<button mw-confirm-click="publish()" mw-confirm-click-message="You are about to overwrite your PUBLISHED content!! Are you SURE you want to publish?">
  Publish
</button>
// /app/directives/mw-confirm-click.js
"use strict";

var module = angular.module( "myApp" );
module.directive( "mwConfirmClick", [
  function( ) {
    return {
      priority: -1,
      restrict: 'A',
      scope: { confirmFunction: "&mwConfirmClick" },
      link: function( scope, element, attrs ){
        element.bind( 'click', function( e ){
          // message defaults to "Are you sure?"
          var message = attrs.mwConfirmClickMessage ? attrs.mwConfirmClickMessage : "Are you sure?";
          // confirm() requires jQuery
          if( confirm( message ) ) {
            scope.confirmFunction();
          }
        });
      }
    }
  }
]);

答案 2 :(得分:45)

对我来说,https://www.w3schools.com/js/js_popup.asp,浏览器的默认确认对话框工作得很好。刚试过这个:

$scope.delete = function() {
    if (confirm("sure to delete")) {
        // todo code for deletion
    }
};

简单.. :)
但我认为你无法自定义它。它将出现在&#34;取消&#34;或&#34;好的&#34;按钮。

修改

如果您使用离子框架,则需要使用ionicPopup对话框,如:

// A confirm dialog


$scope.showConfirm = function() {
   var confirmPopup = $ionicPopup.confirm({
     title: 'Delete',
     template: 'Are you sure you want to delete this item?'
   });

   confirmPopup.then(function(res) {
     if(res) {
       // Code to be executed on pressing ok or positive response
       // Something like remove item from list
     } else {
       // Code to be executed on pressing cancel or negative response
     }
   });
 };

有关详细信息,请参阅:$ionicPopup

答案 3 :(得分:9)

使用核心javascript + angular js非常简单:

{{1}}

如果单击“确定”,则将执行删除操作,否则不会。 * id是您要删除的参数,记录。

答案 4 :(得分:5)

您不想使用terminal: false,因为这样会阻止按钮内部的处理。相反,在link清除attr.ngClick以防止默认行为。

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

app.directive('ngConfirmClick', [
  function() {
    return {
      priority: 1,
      link: function(scope, element, attr) {
        var msg = attr.ngConfirmClick || "Are you sure?";
        var clickAction = attr.ngClick;
        attr.ngClick = "";
        element.bind('click', function(event) {
          if (window.confirm(msg)) {
            scope.$eval(clickAction)
          }
        });
      }
    };
  }
]);

答案 5 :(得分:4)

在今天的日期,这个解决方案对我有用:

/**
 * A generic confirmation for risky actions.
 * Usage: Add attributes: ng-really-message="Are you sure"? ng-really-click="takeAction()" function
 */
angular.module('app').directive('ngReallyClick', [function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            element.bind('click', function() {
                var message = attrs.ngReallyMessage;
                if (message && confirm(message)) {
                    scope.$apply(attrs.ngReallyClick);
                }
            });
        }
    }
}]);

现金:https://gist.github.com/asafge/7430497#file-ng-really-js

答案 6 :(得分:4)

我为这件事创建了一个模块,它依赖于Angular-UI $模态服务。

https://github.com/Schlogen/angular-confirm

答案 7 :(得分:4)

通过使用compile来包装ng-click表达式,可以实现与ng-click一起使用的仅角度解决方案。

<强>指令:

.directive('confirmClick', function ($window) {
  var i = 0;
  return {
    restrict: 'A',
    priority:  1,
    compile: function (tElem, tAttrs) {
      var fn = '$$confirmClick' + i++,
          _ngClick = tAttrs.ngClick;
      tAttrs.ngClick = fn + '($event)';

      return function (scope, elem, attrs) {
        var confirmMsg = attrs.confirmClick || 'Are you sure?';

        scope[fn] = function (event) {
          if($window.confirm(confirmMsg)) {
            scope.$eval(_ngClick, {$event: event});
          }
        };
      };
    }
  };
});

<强> HTML:

<a ng-click="doSomething()" confirm-click="Are you sure you wish to proceed?"></a>

答案 8 :(得分:3)

    $scope.MyUpdateFunction = function () {
        var retVal = confirm("Do you want to save changes?");
        if (retVal == true) {
            $http.put('url', myData).
            success(function (data, status, headers, config) {
                alert('Saved');
            }).error(function (data, status, headers, config) {
                alert('Error while updating');
            });
            return true;
        } else {
            return false;
        }
    }

代码说明了一切

答案 9 :(得分:1)

HTML 5代码示例

<button href="#" ng-click="shoutOut()" confirmation-needed="Do you really want to
shout?">Click!</button>

AngularJs自定义指令代码示例

var app = angular.module('mobileApp', ['ngGrid']);
app.directive('confirmationNeeded', function () {
    return {
    link: function (scope, element, attr) {
      var msg = attr.confirmationNeeded || "Are you sure?";
      var clickAction = attr.ngClick;
      element.bind('click',function (e) {
        scope.$eval(clickAction) if window.confirm(msg)
        e.stopImmediatePropagation();
        e.preventDefault();
       });
     }
    };
});

答案 10 :(得分:1)

确认对话框可以使用AngularJS Material实现:

  

$ mdDialog在应用程序上打开一个对话框,通知用户有关的问题   信息或要求他们做出决定。那里有两个   设置方法:简单的promise API和常规对象语法。

实施示例:Angular Material - Dialogs

答案 11 :(得分:0)

ng-click return confirm 100% works

在html文件中调用delete_plot()函数

GroupOperation groupOperation = group("NotAField").sum("salaries.salary").as("tot‌​al_salary");

将此添加到您的控制器

<i class="fa fa-trash delete-plot" ng-click="delete_plot()"></i> 
 
  

答案 12 :(得分:0)

使用angularjs

中的bootstrap删除确认弹出窗口

非常简单..我使用bootstrap conformation popup有一个解决方案。 我在这提供了

<button ng-click="deletepopup($index)">Delete</button>

在bootstrap模型弹出窗口中:

<div class="modal-footer">
  <a href="" data-dismiss="modal" ng-click="deleteData()">Yes</a>
  <a href="" data-dismiss="modal">No</a>
</div>

JS

var index=0;
$scope.deleteData=function(){
    $scope.model.contacts.splice(index,1);
}
// delete a row 
$scope.deletepopup = function ($index) {
    index=$index;
    $('#myModal').modal('show');
};

当我点击删除按钮bootstrap删除确认弹出窗口将打开,当我单击是按钮行将被删除。

答案 13 :(得分:0)

使用角度承诺$q$window和原生.confirm()模式,这是一个干净而简单的解决方案:

angular.module('myApp',[])
  .controller('classicController', ( $q, $window ) => {
    this.deleteStuff = ( id ) => {
      $q.when($window.confirm('Are you sure ?'))
        .then(( confirm ) => {
          if ( confirm ) {
            // delete stuff
          }
        });
    };
  });

我在这里使用controllerAs语法和ES6箭头功能,但它也在使用{ol}&#39; ES5。

答案 14 :(得分:0)

一个非常简单的角度解决方案

您可以将id与消息一起使用或不使用。如果没有消息,将显示默认消息。

<强>指令

app.directive('ngConfirmMessage', [function () {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            element.on('click', function (e) {
                var message = attrs.ngConfirmMessage || "Are you sure ?";
                if (!confirm(message)) {
                    e.stopImmediatePropagation();
                }
            });
        }
    }
}]);

<强>控制器

$scope.sayHello = function(){
    alert("hello")
}

<强> HTML

带消息

<span ng-click="sayHello()" ng-confirm-message="Do you want to say Hello ?" >Say Hello!</span>

没有消息

<span ng-click="sayHello()" ng-confirm-message>Say Hello!</span>

答案 15 :(得分:0)

如果您使用ui-router,则取消或接受按钮会替换该网址。为了防止这种情况,您可以在条件语句的每种情况下返回false,如下所示:

app.directive('confirmationNeeded', function () {
  return {
    link: function (scope, element, attr) {
      var msg = attr.confirmationNeeded || "Are you sure?";
      var clickAction = attr.confirmedClick;
      element.bind('click',function (event) {
      if ( window.confirm(msg) )
        scope.$eval(clickAction);
      return false;
    });
  }
}; });

答案 16 :(得分:-1)

我希望AngularJS有一个内置的确认对话框。通常,使用自定义对话框比使用内置浏览器更好。

我简短地使用了twitter bootstrap,直到它停止使用版本6.我四处寻找替代品,但我找到的却很复杂。我决定尝试使用JQuery UI。

以下是我打算从ng-grid中删除内容时调用的示例;

    // Define the Dialog and its properties.
    $("<div>Are you sure?</div>").dialog({
        resizable: false,
        modal: true,
        title: "Modal",
        height: 150,
        width: 400,
        buttons: {
            "Yes": function () {
                $(this).dialog('close');
                //proceed with delete...
                /*commented out but left in to show how I am using it in angular
                var index = $scope.myData.indexOf(row.entity);

                $http['delete']('/EPContacts.svc/json/' + $scope.myData[row.rowIndex].RecordID).success(function () { console.log("groovy baby"); });

                $scope.gridOptions.selectItem(index, false);
                $scope.myData.splice(index, 1);
                */
            },
            "No": function () {
                $(this).dialog('close');
                return;
            }
        }
    });

我希望这有助于某人。当我需要升级ui-bootstrap-tpls.js时,我正在拔头发,但它破坏了我现有的对话框。我今天早上上班,尝试了一些事情然后意识到我已经过度复杂了。