Bestätigungsdialog bei ng-click – AngularJS

Lesezeit: 7 Minuten

Benutzer-Avatar
poiuytrez

Ich versuche, einen Bestätigungsdialog auf einem einzurichten ng-click Verwenden einer benutzerdefinierten anglejs-Direktive:

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

Das funktioniert großartig, aber leider werden Ausdrücke innerhalb des Tags mit meiner Direktive nicht ausgewertet:

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

(Name wird dabei nicht ausgewertet). Es scheint am Terminalparameter meiner Direktive zu liegen. Haben Sie eine Idee zur Problemumgehung?

Um meinen Code zu testen:
http://plnkr.co/edit/EHmRpfwsgSfEFVMgRLgj?p=preview

  • Warum verwenden Sie in diesem Fall Terminal? Es scheint, dass es perfekt ohne funktioniert (und Sie wissen es). Ich frage mich nur, warum Sie denken, dass es in Ihrer Richtlinie notwendig ist.

    – Simon Belanger

    19. August 2013 um 12:23 Uhr

  • @SimonBelanger Bei terminal = false wird auch dann, wenn ich im Bestätigungsdialog auf „Abbrechen“ klicke, sayHi() ausgelöst. Mein Ziel ist es nicht, sayHi() aufzurufen, wenn der Benutzer auf Abbrechen klickt.

    – poiuytrez

    19. August 2013 um 12:29 Uhr


Benutzer-Avatar
Michael Niedrig

Wenn es Ihnen nichts ausmacht, nicht zu verwenden ng-click, es funktioniert einwandfrei. Sie können es einfach in etwas anderes umbenennen und das Attribut trotzdem lesen, während Sie vermeiden, dass der Click-Handler zweimal ausgelöst wird, was derzeit ein Problem ist.

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

Ich denke, das Problem ist terminal weist andere Direktiven an, nicht ausgeführt zu werden. Datenbindung mit {{ }} ist nur ein Alias ​​für die ng-bind Richtlinie, die vermutlich durch aufgehoben wird terminal.

  • Dieses Code-Snippet funktioniert nicht mehr mit der aktuellen Version von Angular. scope.$eval(..) sollte durch scope.$apply(..) ersetzt werden

    – CoolTapes

    9. Juni 2014 um 17:07 Uhr

  • Bitte überprüfen Sie diese Frage für einen JS-Bestätigungsdialog mit E2E-Tests stackoverflow.com/questions/16424961/…

    – ndequeker

    4. September 2014 um 12:01 Uhr

  • Das funktioniert, aber was passiert, wenn ich das Kontrollkästchen “Diese Seite vermeiden, um zusätzliche Dialoge zu erstellen” in Chrome aktiviere? :s

    – 0x777

    20. Januar 2016 um 10:11 Uhr


Benutzer-Avatar
mikeborgh

Ein sauberer richtungsweisender Ansatz.

Update: Alte Antwort (2014)

Es fängt im Grunde die ng-click Ereignis, zeigt die in der enthaltene Nachricht an ng-confirm-click="message" Anweisung und fordert den Benutzer zur Bestätigung auf. Wenn Bestätigen geklickt wird, normal ng-click ausgeführt, wenn nicht das Skript beendet und ng-click wird nicht ausgeführt.

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

Codegutschrift an Zach Snow: http://zachsnow.com/#!/blog/2013/confirming-ng-click/

Update: Neue Antwort (2016)

1) Präfix von ‘ng’ in ‘mw’ geändert, da das erstere (‘ng’) für native Winkeldirektiven reserviert ist.

2) Geänderte Direktive, um eine Funktion und Nachricht zu übergeben, anstatt das ng-click-Ereignis abzufangen.

3) Standard “Sind Sie sicher?” hinzugefügt. Nachricht für den Fall, dass mw-confirm-click-message=”” keine benutzerdefinierte Nachricht bereitgestellt wird.

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

  • Nb, erfordert jQuery

    – Eierbeine

    16. Dezember 2014 um 14:09 Uhr


  • Das funktioniert bei mir nicht. Keine Bestätigung wird angezeigt und der Klick wird fortgesetzt. Irgendjemand anderes?

    – OneHoopyFrood

    11. Mai 2015 um 16:59 Uhr

  • Ich denke, es ist eine schlechte Idee, den ng-click-Click-Handler nicht zuerst zu entbinden und sich dann auf Stop Instant und Prevent Default zu verlassen

    – James Kleeh

    15. Oktober 2015 um 2:08 Uhr


  • OneHoopyFrood, Sie müssen eine gültige Funktion in ng-click=”” haben, sonst schlägt es fehl. Vielen Dank.

    – mikeborgh

    8. Mai 2016 um 21:31 Uhr

  • Warum Schritt 2) Geänderte Direktive, um eine Funktion und eine Nachricht zu übergeben, anstatt das ng-click-Ereignis abzufangen?

    – Silber

    7. Juli 2016 um 9:13 Uhr


Benutzer-Avatar
Kailas

Für mich, https://www.w3schools.com/js/js_popup.asp, das standardmäßige Bestätigungsdialogfeld des Browsers hat sehr gut funktioniert. hab das gerade ausprobiert:

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

Einfach.. 🙂
Aber ich denke, man kann es nicht anpassen. Es wird mit der Schaltfläche “Abbrechen” oder “Ok” angezeigt.

BEARBEITEN:

Falls Sie das ionische Framework verwenden, müssen Sie das ionicPopup-Dialogfeld wie folgt verwenden:

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

Weitere Informationen finden Sie unter: $ionicPopup

  • Es sieht in der Tat sauber aus, aber ich denke, es ist gegen den deklarativen Ansatz in Angular. Mit diesem Ansatz ist es einfach, Ansichtslogik in den Controller zu integrieren. Wenn man kann, kann es hilfreich sein, den Controller von UI-Elementen sauber zu halten.

    – Jim Aho

    15. April 2015 um 11:42 Uhr

  • Sie können die loswerden == truewas in diesem Fall völlig unnötig ist, denn confirm() gibt bereits einen booleschen Wert zurück. Sie müssen JS nicht dazu bringen, es zu erzwingen und mit wahr zu vergleichen.

    – Leo Lam

    27. April 2015 um 10:12 Uhr


Benutzer-Avatar
VBMali

Es ist so einfach, Kern-Javascript + Winkel-js zu verwenden:

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

Wenn Sie auf OK klicken, wird der Löschvorgang ausgeführt, andernfalls nicht. * id ist der Parameter, Datensatz, den Sie löschen möchten.

Sie möchten nicht verwenden terminal: false da dies die Verarbeitung innerhalb der Schaltfläche blockiert. Stattdessen in Ihrem link klar die attr.ngClick um das Standardverhalten zu verhindern.

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

  • Funktioniert in der Version von Angular, auf die Sie in Plunker verweisen, aber wenn Sie auf ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js verweisen, funktioniert es nicht wie erwartet.

    – ChrisW

    25. März 2014 um 19:04 Uhr

  • Letztendlich funktioniert mein vorgeschlagener Ansatz nur in einigen Fällen, da ngClick viel mehr als nur eine einfache Bindung an “Klick” leistet. Ich denke, der richtigere Ansatz besteht darin, die Bestätigung im ng-click-Handler statt über ein separates Attribut zu behandeln.

    – Stepan Riha

    25. März 2014 um 22:18 Uhr

Benutzer-Avatar
om471987

    $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 sagt alles

  • Funktioniert in der Version von Angular, auf die Sie in Plunker verweisen, aber wenn Sie auf ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js verweisen, funktioniert es nicht wie erwartet.

    – ChrisW

    25. März 2014 um 19:04 Uhr

  • Letztendlich funktioniert mein vorgeschlagener Ansatz nur in einigen Fällen, da ngClick viel mehr als nur eine einfache Bindung an “Klick” leistet. Ich denke, der richtigere Ansatz besteht darin, die Bestätigung im ng-click-Handler statt über ein separates Attribut zu behandeln.

    – Stepan Riha

    25. März 2014 um 22:18 Uhr

Benutzer-Avatar
Nanu

Zum heutigen Datum funktioniert diese Lösung für mich:

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

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

1156760cookie-checkBestätigungsdialog bei ng-click – AngularJS

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy