86

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

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

这很好用,但不幸的是,使用我的指令的标签内的表达式不会被评估:

<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

4

17 回答 17

93

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

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

我认为问题在于terminal指示其他指令不要运行。数据绑定 with{{ }}只是该ng-bind指令的别名,它可能被terminal.

于 2013-08-19T12:36:10.283 回答
58

一个干净的指令方法。

更新:旧答案(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') 是为原生 Angular 指令保留的。

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();
          }
        });
      }
    }
  }
]);
于 2014-06-10T05:08:31.343 回答
47

For me, https://www.w3schools.com/js/js_popup.asp, the default confirmation dialog box of the browser worked a great deal. just tried out this:

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

Simple.. :)
But I think you can't customize it. It will appear with "Cancel" or "Ok" button.

EDIT:

In case you are using ionic framework, you need to use the ionicPopup dialog as in:

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

For more details, refer: $ionicPopup

于 2014-10-01T07:30:57.583 回答
11

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

$scope.delete = function(id) 
    { 
       if (confirm("Are you sure?"))
           {
                //do your process of delete using angular js.
           }
   }

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

于 2015-06-08T11:21:40.187 回答
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)
          }
        });
      }
    };
  }
]);
于 2014-03-12T04:05:03.333 回答
4

I created a module for this very thing that relies on the Angular-UI $modal service.

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

于 2014-12-02T18:54:25.777 回答
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

于 2014-07-10T19:03:19.543 回答
4
    $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;
        }
    }

代码说明一切

于 2014-05-02T23:39:44.130 回答
4

An angular-only solution that works alongside ng-click is possible by using compile to wrap the ng-click expression.

Directive:

.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>
于 2015-08-08T16:13:20.180 回答
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();
       });
     }
    };
});
于 2015-01-09T09:42:00.593 回答
1

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

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

实现示例:Angular Material - 对话框

于 2017-06-08T11:49:49.073 回答
0

$q这是一个使用 Angular Promise和$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 箭头函数,但它也适用于普通的 ES5。

于 2016-05-07T06:57:12.490 回答
0

在angularjs中使用引导程序删除确认弹出窗口

非常简单..我有一个解决方案,使用引导构造弹出窗口。我在这里提供

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

在引导模型弹出窗口中:

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

当我单击删除按钮引导删除配置弹出窗口将打开,当我单击是按钮行将被删除。

于 2017-05-24T10:27:52.107 回答
0

如果您使用 ui-router,取消或接受按钮会替换 url。为了防止这种情况,您可以在条件句的每种情况下返回 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;
    });
  }
}; });
于 2015-07-21T11:24:16.453 回答
0

ng-click 返回确认 100% 有效

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

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

将此添加到您的控制器

    $scope.delete_plot = function(){
        check = confirm("Are you sure to delete this plot?")
        if(check){
            console.log("yes, OK pressed")
        }else{
            console.log("No, cancel pressed")

        }
    }
于 2020-09-12T20:44:52.670 回答
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>
于 2016-01-20T12:12:50.170 回答
-1

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

我短暂地使用了 twitter 引导程序,直到它在第 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 时,我正在拔头发,但它破坏了我现有的对话框。我今天早上开始工作,尝试了一些事情,然后意识到我过于复杂了。

于 2014-02-28T13:17:41.040 回答