Hộp thoại xác nhận khi ng-click - AngularJS


85

Tôi đang cố gắng thiết lập hộp thoại xác nhận trên ng-clickchỉ thị sử dụng lệnh anglejs tùy chỉnh:

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

Điều này hoạt động tốt nhưng rất tiếc, các biểu thức bên trong thẻ sử dụng lệnh của tôi không được đánh giá:

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

(tên không được đánh giá là trường hợp này). Nó dường như là do tham số đầu cuối của chỉ thị của tôi. Bạn có bất kỳ ý tưởng về cách giải quyết nào không?

Để kiểm tra mã của tôi: http://plnkr.co/edit/EHmRpfwsgSfEFVMgRLgj?p=preview


Tại sao bạn sử dụng thiết bị đầu cuối trong trường hợp này? Có vẻ như nó hoạt động hoàn hảo mà không cần (và bạn biết điều đó). Tôi chỉ tự hỏi tại sao bạn nghĩ rằng nó cần thiết trong chỉ thị của bạn.
Simon Belanger

@SimonBelanger Với terminal = false, ngay cả khi tôi nhấp vào "hủy" trong hộp thoại xác nhận, sayHi () vẫn được kích hoạt. Mục tiêu của tôi là không gọi sayHi () nếu người dùng nhấp vào hủy.
poiuytrez

Câu trả lời:


92

Nếu bạn không phiền khi không sử dụng ng-click, nó vẫn hoạt động tốt. Bạn chỉ có thể đổi tên nó thành một cái gì đó khác và vẫn đọc thuộc tính, đồng thời tránh việc trình xử lý nhấp chuột bị kích hoạt hai lần vấn đề hiện có.

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

Tôi nghĩ rằng vấn đề là terminalcác lệnh khác không chạy. Liên kết dữ liệu với {{ }}chỉ là một bí danh cho ng-bindchỉ thị, có lẽ đã bị hủy bỏ bởi terminal.


13
Đoạn mã này không còn hoạt động với phiên bản hiện tại của angle. . Phạm vi $ eval (..) nên được thay thế với phạm vi áp dụng $ (..).
CoolTapes

vui lòng kiểm tra câu hỏi này để biết hộp thoại xác nhận JS với E2E-tests stackoverflow.com/questions/16424961/…
ndequeker

Điều này hoạt động, nhưng điều gì sẽ xảy ra nếu tôi chọn hộp kiểm "Tránh trang này để tạo hộp thoại bổ sung" của chrome? : s
bigpony

58

Một cách tiếp cận chỉ thị sạch.

Cập nhật: Câu trả lời cũ (2014)

Về cơ bản, nó chặn ng-clicksự kiện, hiển thị thông báo có trong ng-confirm-click="message"chỉ thị và yêu cầu người dùng xác nhận. Nếu xác nhận được nhấp vào ng-click, lệnh thực thi bình thường , nếu không, tập lệnh kết thúc và ng-clickkhông được chạy.

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

Mã tín dụng cho Zach Snow: http://zachsnow.com/#!/blog/2013/confirming-ng-click/

Cập nhật: Câu trả lời mới (2016)

1) Đã thay đổi tiền tố từ 'ng' thành 'mw' vì tiền tố trước đây ('ng') được dành riêng cho các chỉ thị góc gốc.

2) Chỉ thị được sửa đổi để chuyển một hàm và thông báo thay vì chặn sự kiện ng-click.

3) Đã thêm mặc định "Bạn có chắc không?" trong trường hợp thông báo tùy chỉnh không được cung cấp cho 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, đòi hỏi jQuery
eggonlegs

1
Điều này không hiệu quả với tôi. Không có xác nhận hiển thị và nhấp chuột tiếp tục. Ai khác?
OneHoopyFrood

Tôi nghĩ rằng đó là một ý tưởng tồi để không unbind các ng nhấp chuột nhấp chuột xử lý đầu tiên và sau đó dựa vào dừng trước mắt và ngăn chặn mặc định
James Kleeh

OneHoopyFrood, bạn phải có một hàm hợp lệ trong ng-click = "", nếu không nó sẽ không thành công. Cảm ơn.
mikeborgh

Tại sao lại là bước 2) Chỉ thị được sửa đổi để chuyển một hàm và thông báo thay vì chặn sự kiện ng-click?
Bạc,

46

Đối với tôi, https://www.w3schools.com/js/js_popup.asp , hộp thoại xác nhận mặc định của trình duyệt hoạt động rất hiệu quả. vừa thử cái này:

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

Đơn giản .. :)
Nhưng tôi nghĩ bạn không thể tùy chỉnh nó. Nó sẽ xuất hiện với nút "Hủy" hoặc "Ok".

BIÊN TẬP:

Trong trường hợp bạn đang sử dụng ionic framework, bạn cần sử dụng hộp thoại ionicPopup như trong:

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

Để biết thêm chi tiết, hãy tham khảo: $ ionicPopup


Nó thực sự trông sạch sẽ, tuy nhiên tôi nghĩ nó chống lại cách tiếp cận khai báo trong Angular. Thật dễ dàng để đặt logic chế độ xem bên trong bộ điều khiển với cách tiếp cận này. Nếu có thể, bạn nên giữ bộ điều khiển sạch sẽ khỏi các phần tử giao diện người dùng.
Jim Aho

1
Bạn có thể loại bỏ == true, hoàn toàn không cần thiết trong trường hợp này, vì confirm()đã trả về boolean. Không cần phải gõ JS cưỡng chế và so sánh nó với true.
Léo Lam

10

Thật đơn giản bằng cách sử dụng javascript lõi + js góc cạnh:

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

Nếu bạn nhấp vào OK, thì thao tác xóa sẽ thực hiện, ngược lại thì không. * id là tham số, bản ghi mà bạn muốn xóa.


5

Bạn không muốn sử dụng terminal: falsevì đó là thứ đang chặn quá trình xử lý bên trong nút. Thay vào đó, linkrõ ràng của bạn attr.ngClickđể ngăn chặn hành vi mặc định.

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

Hoạt động trong phiên bản Angular mà bạn tham chiếu trong plunker, nhưng nếu bạn tham chiếu ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js thì nó không hoạt động như mong đợi.
ChrisW

Cuối cùng, cách tiếp cận được đề xuất của tôi chỉ hoạt động trong một số trường hợp, bởi vì ngClick thực hiện nhiều cách hơn là liên kết simlpy với 'nhấp chuột'. Tôi nghĩ cách tiếp cận đúng hơn là xử lý xác nhận trong trình xử lý ng-click thay vì thông qua một thuộc tính riêng biệt.
Stepan Riha

4

Trong ngày hôm nay, giải pháp này phù hợp với tôi:

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

Tín dụng: https://gist.github.com/asafge/7430497#file-ng-really-js



4

ng-clickCó thể sử dụng giải pháp chỉ góc hoạt động bên cạnh bằng cách sử dụng biên dịch để bọc ng-clickbiểu thức.

Chỉ thị:

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

Code nói lên mọi thứ


1

Mẫu mã HTML 5

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

Mẫu mã Chỉ thị tùy chỉnh 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

Hộp thoại xác nhận có thể được triển khai bằng AngularJS Material :

$ mdDialog mở một hộp thoại trên ứng dụng để thông báo cho người dùng về thông tin quan trọng hoặc yêu cầu họ đưa ra quyết định. Có hai cách tiếp cận để thiết lập: một API lời hứa đơn giản và cú pháp đối tượng thông thường.

Ví dụ triển khai: Vật liệu góc - Hộp thoại


0

Nếu bạn sử dụng ui-router, nút hủy hoặc chấp nhận sẽ thay thế url. Để tránh điều này, bạn có thể trả về false trong mỗi trường hợp của câu điều kiện như sau:

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

Một giải pháp góc cạnh rất đơn giản

Bạn có thể sử dụng id với một tin nhắn hoặc không. Nếu không có thông báo, thông báo mặc định sẽ hiển thị.

Chỉ thị

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

Bộ điều khiển

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

HTML

Với một tin nhắn

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

Không có lời nhắn

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

0

Đây là một giải pháp làm sạch và đơn giản sử dụng những lời hứa góc $q, $windowvà có nguồn gốc .confirm()phương thức:

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

Ở đây tôi đang sử dụng controllerAscú pháp và các hàm mũi tên ES6 nhưng nó cũng hoạt động trong ES5 đơn giản.


0

Xóa cửa sổ bật lên xác nhận bằng bootstrap trong anglejs

rất đơn giản .. Tôi có một giải pháp cho việc này bằng cách sử dụng cửa sổ bật lên cấu hình bootstrap. Ở đây tôi được cung cấp

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

trong cửa sổ bật lên mô hình 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');
};

khi tôi nhấp vào nút xóa, cửa sổ bật lên xóa cấu trúc khởi động sẽ mở ra và khi tôi nhấp vào có hàng nút sẽ bị xóa.


0

ng-click quay lại xác nhận 100% hoạt động

trong tệp html, hãy gọi hàm delete_plot ()

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

Thêm cái này vào bộ điều khiển của bạn

    $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

Tôi ước gì AngularJS có một hộp thoại xác nhận được tích hợp sẵn. Thông thường, sẽ đẹp hơn nếu có một hộp thoại tùy chỉnh hơn là sử dụng hộp thoại cài sẵn trong trình duyệt.

Tôi đã sử dụng bootstrap của twitter một thời gian ngắn cho đến khi nó không còn được tiếp tục với phiên bản 6. Tôi đã tìm kiếm các lựa chọn thay thế, nhưng những thứ tôi thấy rất phức tạp. Tôi quyết định dùng thử giao diện người dùng JQuery.

Đây là mẫu của tôi mà tôi gọi khi tôi chuẩn bị xóa nội dung nào đó khỏi 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;
            }
        }
    });

Tôi hi vọng điêu nay se giup được ai đo. Tôi đang nhổ tóc khi cần nâng cấp ui-bootstrap-tpls.js nhưng nó đã phá vỡ hộp thoại hiện có của tôi. Tôi đi làm sáng nay, thử một vài thứ và sau đó nhận ra rằng tôi đã quá phức tạp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.