2014-04-07 18 views
5

Ho un'app angolare con un elenco di elementi. Sto cercando di implementare un modal personalizzato "Conferma cancellazione", in modo che quando l'utente fa clic sul pulsante "Elimina" accanto a un elemento, il modale si apre per confermare l'eliminazione. Facendo clic su "Sì", viene attivata una funzione deleteItem(). Il mio problema è che il server sta restituendo 404 non trovato per la richiesta di cancellazione. Funziona quando uso la finestra di conferma standard di jquery, quindi suppongo che l'ID oggetto non venga passato attraverso la modale alla funzione di cancellazione. qualcuno può aiutare?Eliminazione personalizzata conferma in angularJS

<div class="span6"> 
     <table class="table table-striped table-condensed"> 
      <thead> 
      <tr> 
       <th style="min-width: 80px;">Name:</th> 
       <th style="width:20px;"> </th> 
       <th style="width:20px;"> </th> 
      </tr> 
      </thead> 
      <tbody> 
      <tr ng-repeat="item in items | filter:query | orderBy:orderProp"> 
       <td>{{ item.name }}</td> 


       <td><a ng-click="editItem(item.id)" class="btn btn-small btn-primary">Edit</a></td> 
       <td><a ng-click="openModal(item.id)" class="btn btn-small btn-success">Delete</a></td> 

      </tr> 
      </tbody> 
     </table> 

      <modal-dialog show='modalShown' id = "itemModal" width='300px' height='40%'> 
        <p>Are you sure you want to delete this item?<p> 
         <button ng-click = "deleteItem(item.id)" class = "link">Yes</button> 
      </modal-dialog> 

    </div> 

Ecco il controllore:

angular.module('myApp.controllers') 
    .controller('ItemCtrl', ['$scope', 'ItemsFactory', 'ItemFactory', '$location', '$route', 
     function ($scope, ItemsFactory, ItemFactory, $location, $route) { 

      $scope.modalShown = false; 

     //callback for ng-click 'deleteItem': 

      $scope.openModal = function (itemId) { 
       $scope.modalShown = !$scope.modalShown; 

      }; 

     //callback for ng-click 'deleteItem': 

      $scope.deleteItem = function (itemId) { 

       ItemFactory.delete({ id: itemId }).$promise.then(function (items){ 
        $scope.items = items; 
        $location.path('/items'); 
        $route.reload(); 
       }, function (err) { 
        console.error(err); 
       });  

       // } 

      }; 
+0

http://stackoverflow.com/questions/29602222/create-a-simple-bootstrap-yes-no-confirmation -o-solo-notifica-avviso-in-angu/37265529 # 37265529 –

risposta

2

L'item è solo "conosciuto" all'interno del perimetro creato dal ngRepeat per ciascun elemento.
<modal-dialog> non è all'interno di tale ambito e non è a conoscenza di item.

Si potrebbe refactoring del codice come questo:

// In HTML: 
<modal-dialog ...> 
    ... 
    <button ng-click="deleteItem()" ... 

// In controller: 
$scope.modalShown = false; 
$scope.itemToDeleteId; 
... 
$scope.openModal = function (itemId) { 
    $scope.itemToDeleteId = itemId; 
    $scope.modalShown = true; 
}; 
... 
$scope.deleteItem = function() { 
    if (!$scope.itemToDeleteId) { return; } 
    var itemId = $scope.itemToDeleteId; 
    $scope.itemToDeleteId = null; 
    ... 
18

Ho passato un po 'di tempo su questo, ma ho voluto fare tutto in un click (come una normale finestra di dialogo di conferma finestra). È iniziata con la domanda "How do I intercept ng-click in angularJS?"

Ho sviluppato una direttiva e un servizio che funzionano con l'UI Bootstrap Modal per creare una finestra di dialogo modale che conferma un'azione di ng-clic prima di procedere.

Demo on Plunker o qui:

/* 
Confirm an ng-click action with a modal dialog window (requires UI Bootstrap Modal service) 
Using this modal requires two things: apply the attribute to the dom element and prepend 
the confirmClick() action to the ng-click attribute. 

    <a href="#" ng-click="confirmClick() && deleteItem(item)" confirm-click>Delete</a> 

*/ 
.directive('confirmClick', ['$q', 'dialogModal', function($q, dialogModal) { 
    return { 
     link: function (scope, element, attrs) { 
      // ngClick won't wait for our modal confirmation window to resolve, 
      // so we will grab the other values in the ngClick attribute, which 
      // will continue after the modal resolves. 
      // modify the confirmClick() action so we don't perform it again 
      // looks for either confirmClick() or confirmClick('are you sure?') 
      var ngClick = attrs.ngClick.replace('confirmClick()', 'true') 
       .replace('confirmClick(', 'confirmClick(true,'); 

      // setup a confirmation action on the scope 
      scope.confirmClick = function(msg) { 
       // if the msg was set to true, then return it (this is a workaround to make our dialog work) 
       if (msg===true) { 
        return true; 
       } 
       // msg can be passed directly to confirmClick('are you sure?') in ng-click 
       // or through the confirm-click attribute on the <a confirm-click="Are you sure?"></a> 
       msg = msg || attrs.confirmClick || 'Are you sure?'; 
       // open a dialog modal, and then continue ngClick actions if it's confirmed 
       dialogModal(msg).result.then(function() { 
        scope.$eval(ngClick); 
       }); 
       // return false to stop the current ng-click flow and wait for our modal answer 
       return false; 
      }; 
     } 
    } 
}]) 

/* 
Open a modal confirmation dialog window with the UI Bootstrap Modal service. 
This is a basic modal that can display a message with okay or cancel buttons. 
It returns a promise that is resolved or rejected based on okay/cancel clicks. 
The following settings can be passed: 

    message   the message to pass to the modal body 
    title   (optional) title for modal window 
    okButton  text for OK button. set false to not include button 
    cancelButton text for Cancel button. ste false to not include button 

*/ 
.service('dialogModal', ['$modal', function($modal) { 
    return function (message, title, okButton, cancelButton) { 
     // setup default values for buttons 
     // if a button value is set to false, then that button won't be included 
     okButton = okButton===false ? false : (okButton || 'Confirm'); 
     cancelButton = cancelButton===false ? false : (cancelButton || 'Cancel'); 

     // setup the Controller to watch the click 
     var ModalInstanceCtrl = function ($scope, $modalInstance, settings) { 
      // add settings to scope 
      angular.extend($scope, settings); 
      // ok button clicked 
      $scope.ok = function() { 
       $modalInstance.close(true); 
      }; 
      // cancel button clicked 
      $scope.cancel = function() { 
       $modalInstance.dismiss('cancel'); 
      }; 
     }; 

     // open modal and return the instance (which will resolve the promise on ok/cancel clicks) 
     var modalInstance = $modal.open({ 
      template: '<div class="dialog-modal"> \ 
       <div class="modal-header" ng-show="modalTitle"> \ 
        <h3 class="modal-title">{{modalTitle}}</h3> \ 
       </div> \ 
       <div class="modal-body">{{modalBody}}</div> \ 
       <div class="modal-footer"> \ 
        <button class="btn btn-primary" ng-click="ok()" ng-show="okButton">{{okButton}}</button> \ 
        <button class="btn btn-warning" ng-click="cancel()" ng-show="cancelButton">{{cancelButton}}</button> \ 
       </div> \ 
      </div>', 
      controller: ModalInstanceCtrl, 
      resolve: { 
       settings: function() { 
        return { 
         modalTitle: title, 
         modalBody: message, 
         okButton: okButton, 
         cancelButton: cancelButton 
        }; 
       } 
      } 
     }); 
     // return the modal instance 
     return modalInstance; 
    } 
}]) 
+1

Assolutamente fantastico! –

+0

Questo è fantastico, grazie – ccook

+0

@dustin Potresti dirmi come eliminare con l'id piuttosto che l'indice di esso. se ci sarà un id per ogni oggetto. sto usando http.delete per eliminare piuttosto che splicing – codelearner

0

Una direttiva personalizzato:

/** 
* A generic confirmation for risky actions. 
* Usage: Add attributes: ng-really-message="Really?" 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); 
       } 
      }); 
     } 
    } 
}]); 
+0

in questo modo come cambieresti lo stile della casella di conferma? – Martian2049

Problemi correlati