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

IT技术 javascript angularjs angularjs-directive angularjs-scope
2021-03-15 21:26:31

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

6个回答

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

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

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

此代码片段不再适用于当前版本的 angular。scope.$eval(..) 应该替换为 scope.$apply(..)
2021-05-02 21:26:31
请检查此问题以获取带有 E2E 测试的 JS 确认对话框 stackoverflow.com/questions/16424961/...
2021-05-12 21:26:31
这有效,但是如果我选中 chrome 的复选框“避免此页面创建其他对话框”会发生什么?:s
2021-05-16 21:26:31

一种干净的指令方法。

更新:旧答案(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();
          }
        });
      }
    }
  }
]);
OneHoopyFrood,你必须在 ng-click="" 中有一个有效的函数,否则它会失败。谢谢。
2021-04-23 21:26:31
我认为不先解除绑定 ng-click 点击处理程序然后依靠立即停止并防止默认值是一个坏主意
2021-04-26 21:26:31
Nb,需要 jQuery
2021-04-28 21:26:31
这对我不起作用。没有确认显示,点击继续。还有谁?
2021-04-30 21:26:31
为什么步骤 2) 修改指令以传递函数和消息而不是拦截 ng-click 事件?
2021-05-15 21:26:31

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

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

简单.. :)
但我认为你不能自定义它。它将出现“取消”或“确定”按钮。

编辑:

如果您使用 ionic 框架,则需要使用 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 元素的清洁会很有帮助。
2021-04-25 21:26:31
你可以去掉 ,== true在这种情况下这完全没有必要,因为它confirm()已经返回了一个布尔值。无需让 JS 强制键入并将其与 true 进行比较。
2021-05-09 21:26:31

使用核心 javascript + angular js 就这么简单:

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

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

您不想使用,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,它不会按预期工作。
2021-04-25 21:26:31
最终,我建议的方法仅适用于某些情况,因为 ngClick 不仅仅是简单地绑定到“click”。我认为更正确的方法是在 ng-click 处理程序中处理确认,而不是通过单独的属性。
2021-05-14 21:26:31