2014-10-30 29 views
5

Ho la seguente direttiva per mostrare un popup per confermare un'esecuzione di una funzione al clic.Direttiva chiamata angolare dal controllore

Ora vorrei utilizzarlo nel mio controller per mostrare un popup se le proprietà di un oggetto sono state modificate e l'utente vuole cambiare la posizione senza salvare prima l'oggetto. È possibile?

angular.module('app.confirm', [ 
    'ui.bootstrap', 
    'template/modal/confirm.html', 
]) 

.controller('ConfirmModalController', ['$scope', '$modalInstance', function($scope, $modalInstance) { 
    $scope.confirm = function() { 
     $modalInstance.close(); 
    }; 

    $scope.cancel = function() { 
     $modalInstance.dismiss('cancel'); 
    }; 
}]) 

.directive('confirm', ['$modal', function($modal) { 
    return { 
     restrict: 'A', 
     scope: { 
      confirm: '&', 
      title: '@confirmTitle', 
      message: '@confirmMessage', 
      confirmButtonText: '@confirmButtonText', 
      cancelButtonText: '@cancelButtonText' 
     }, 
     link: function(scope, element, attributes) { 
      element.bind('click', function() { 
       var modal= $modal.open({ 
        controller: 'ConfirmModalController', 
        templateUrl: 'template/modal/confirm.html', 
        size: 'sm', 
        scope: scope 
       }); 

       modal.result.then(function() { 
        scope.confirm(); 
       }, function() { 
        // Modal dismissed 
       }); 
      }); 
     } 
    }; 
}]); 

angular.module('template/modal/confirm.html', []).run(['$templateCache', function($templateCache) { 
    $templateCache.put(
     'template/modal/confirm.html', 
     '<div class="modal-header" ng-show="title">' + 
      '<strong class="modal-title">{{title}}</strong>' + 
     '</div>' + 
     '<div class="modal-body">' + 
      '{{message}}' + 
     '</div>' + 
     '<div class="modal-footer">' + 
      '<a href="javascript:;" class="btn btn-link pull-left" ng-click="cancel()">{{cancelButtonText}}</a>' + 
      '<button class="btn btn-danger" ng-click="confirm()">{{confirmButtonText}}</button>' + 
     '</div>' 
    ); 
}]); 

Si può usare così:

<button 
    confirm="delete(id)" 
    confirm-title="Really?" 
    confirm-message="Really delete?" 
    confirm-button-text="Delete" 
    cancel-button-text="Cancel" 
    class="btn btn-danger" 
> 
    Delete 
</button> 
+0

Si potrebbe implementare controllo del vostro direttiva come fornitore. La direttiva quindi utilizzerà il provider per implementare se stesso. Ti permetterebbe anche di creare lo stesso componente interamente in script iniettando il tuo provider nel controller. ngDialog è implementato in questo modo. https: // GitHub.com/likeastore/ngDialog – mccainz

risposta

0

È possibile guardare per un cambiamento in una proprietà di validità del direttiva.

Ad esempio, aggiungere un confirm-show-when

<button 
    confirm="delete(id)" 
    ... 
    confirm-show-when="state.showConfirmDialog" 
    ... 
> 
    Delete 
</button> 

aggiungerlo alla tua definizione direttiva

.directive('confirm', ['$modal', function($modal) { 
    return { 
     restrict: 'A', 
     scope: { 
      confirm: '&', 
      title: '@confirmTitle', 
      message: '@confirmMessage', 
      confirmButtonText: '@confirmButtonText', 
      cancelButtonText: '@cancelButtonText', 
      showWhen: '=confirmShowWhen' 
     }, 
     link: function(scope, element, attributes) { 
      var showModal = function() { 
       var modal= $modal.open({ 
        controller: 'ConfirmModalController', 
        templateUrl: 'template/modal/confirm.html', 
        size: 'sm', 
        scope: scope 
       }); 

       modal.result.then(function() { 
        scope.confirm(); 
       }, function() { 
        // Modal dismissed 
        // set showWhen back to false 
        scope.showWhen = false; 
       }); 
      }; 
      element.bind('click', showModal); 
      scope.$watch('showWhen', function(newVal) { 
       if (newVal) {showModal()}; 
      }); 
     } 
    }; 
}]); 

E nel controller è sufficiente impostare la showConfirmDialog al vero quando si vuole vedere.

// controller code 
// set up the state object so we use the 'dot' notation 
$scope.state = { showConfirmDialog: false }; 
// other controller code 
if (userWantsToDelete) { 
    $scope.state.showConfirmDialog = true; 
} 
7

N0- soluzioni $ orologi:

1.
fornire il proprio controller con un callback, che riceve un'interfaccia esposta dal direttiva. Il tuo controller cattura l'interfaccia e la usa nello script come desidera. Semplice e può essere implementato su qualsiasi direttiva esistente.

Plnkr for interface callback

app.directive("simpleDialog",function(simpleDialog){ 
    return{ 
     template:"<button ng-click='open()'>open from directive</button>", 
     scope:{ 
     onInit : "&onInit" 
     }, 
     link: function(scope){ 
     scope.open = simpleDialog.open; 
     scope.onInit({interface:{open:scope.open}}); 
     } 
    } 
    }); 

molto più complicato, ma un modello eccellente ...

2.
Se si desidera effettuare una direttiva che ha anche un'interfaccia programmabile allora vi consiglio l'attuazione del nucleo della direttiva come fornitore. È quindi possibile implementare la direttiva in base al provider e nei casi in cui si desidera accedere completamente alla stessa funzionalità attraverso lo script, è possibile operare direttamente sul provider immettendolo nel controller.

Questa è la strategia di attuazione seguito da ngDialog

Inoltre, come si sta sta creando una finestra di conferma si potrebbe trovare questo schema utile come metodo aperto potrebbe restituire una promessa che può essere risolto o rifiutata dalla finestra, consentendo al controller di rispondere in base alla promessa.

PLNKR DEMO

<!DOCTYPE html> 
 
<html> 
 

 
    <head> 
 
    <script data-require="[email protected]*" data-semver="1.3.0" src="//code.angularjs.org/1.3.0/angular.js"></script> 
 
    <link rel="stylesheet" href="style.css" /> 
 
    
 
    </head> 
 

 
    <body ng-controller="myCtrl"> 
 
    
 
    <h1>Exposing a Directive interface to a controller</h1> 
 
    <div simple-dialog on-init="initCallback(interface)"></div> 
 
    <p><button ng-click="open()">Open from controller</button></p> 
 
    <p><button ng-click="open2()">Open from Exposed interface</button></p> 
 
    
 
    <script> 
 
     
 
     
 
     var app = angular.module("app",[]); 
 
     
 
     app.controller("myCtrl",function(simpleDialog,$scope){ 
 
     $scope.open = simpleDialog.open; 
 
     $scope.open2 = function(){ 
 
      this.interface.open(); 
 
     } 
 
     $scope.initCallback = function(interface){ 
 
      this.interface = interface; 
 
     } 
 
     }); 
 
     
 
    
 
     app.provider("simpleDialog",function(){ 
 
     
 
     this.$get = function(){ 
 
      
 
      var publicMethods={ 
 
      open:function(){ 
 
       alert("Impelment Dialog Here"); 
 
      } 
 
      } 
 
      
 
      return publicMethods; 
 
      
 
     } 
 
     }); 
 
     
 
     app.directive("simpleDialog",function(simpleDialog){ 
 
     return{ 
 
      template:"<button ng-click='open()'>open from directive</button>", 
 
      scope:{ 
 
      onInit : "&onInit" 
 
      }, 
 
      link: function(scope){ 
 
      scope.open = simpleDialog.open; 
 
      scope.onInit({interface:{open:scope.open}}); 
 
      } 
 
     } 
 
     }); 
 
     
 
     angular.bootstrap(document,["app"]); 
 
     
 
    </script> 
 
    </body> 
 
</html>

Problemi correlati