单击ng的确认对话框-AngularJS


85

我正在尝试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


为什么在这种情况下使用终端?似乎在没有(您知道)的情况下它可以完美工作。我只是想知道为什么您认为在您的指令中有必要。
西蒙·贝朗厄尔

@SimonBelanger如果终端= false,即使我在确认对话框中单击“取消”,也会触发sayHi()。我的目标是如果用户单击“取消”,则不调用sayHi()。
poiuytrez

Answers:


92

如果您不介意不使用ng-click,则可以正常使用。您可以将其重命名为其他名称,然后仍然读取属性,同时避免单击处理程序被两次触发而导致当前出现问题。

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

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


13
此代码段不再适用于当前版本的angular。scope。$ eval(..)应该替换为scope。$ apply(..)
CoolTapes

请检查这个问题与端到端的测试一个JS确认对话框 stackoverflow.com/questions/16424961/...
ndequeker

这行得通,但是如果我选中Chrome的复选框“避免此页面以创建其他对话框”,会发生什么?:s
bigpony '16

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”)保留用于本机角度指令。

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

8
Nb,需要jQuery
eggonlegs 2014年

1
这对我不起作用。没有确认显示,单击继续。还有谁?
OneHoopyFrood 2015年

我认为不先解除ng-click单击处理程序的绑定然后依赖立即停止并防止默认操作是一个坏主意
James Kleeh 2015年

OneHoopyFrood,您必须在ng-click =“”中具有有效的函数,否则它将失败。谢谢。
mikeborgh

为什么要执行步骤2)修改的指令以传递函数和消息,而不是拦截ng-click事件?
银色

46

对我来说,https://www.w3schools.com/js/js_popup.asp,浏览器的默认确认对话框非常有用。刚刚尝试了这个:

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

很简单.. :)
但是我认为您不能自定义它。它将显示“取消”或“确定”按钮。

编辑:

如果使用的是离子框架,则需要使用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


它确实看起来很干净,但是我认为这与Angular中的声明式方法背道而驰。通过这种方法很容易将视图逻辑放入控制器中。如果可以的话,使控制器与UI元素保持清洁可能会有所帮助。
Jim Aho 2015年

1
您可以摆脱,== true在这种情况下完全不需要,因为confirm()已经返回了布尔值。无需让JS输入强制并将其与true进行比较。
莱奥林

10

使用核心javascript + angular js是如此简单:

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

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


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

在您在plunker中引用的Angular版本中可以使用,但是如果您引用ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js,则它无法正常工作。
ChrisW 2014年

最终,我建议的方法仅在某些情况下有效,因为ngClick的作用远不止简单绑定到“ click”。我认为更正确的方法是在ng-click处理程序中处理确认,而不是通过单独的属性。
Stepan Riha 2014年

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



4

ng-click通过使用compile来包装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>

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

代码说明了一切


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

1

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

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

实施示例:角度材料-对话框


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

0

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

您可以在消息中使用ID,也可以不使用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>

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箭头功能,但它也可以在普通ES5中使用。


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

当我单击“删除”按钮时,引导程序删除配置弹出窗口将打开,当我单击“是”时,将删除行。


0

ng点击返回确认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")

        }
    }

-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时,我正在拔头发,但这打破了我现有的对话框。我今天早上开始工作,尝试了几件事,然后意识到我太复杂了。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.