Angular directive call from controller

I have the following directive showing a popup to confirm the function is executed on click.

Now I would like to use it in my controller to show a popup if the properties of the object have been changed and the user wants to change the location without saving the object before. Is it possible?

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

You can use it like this:

 <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> 
+5
source share
2 answers

N0- $ watch solutions:

1.
Provide your controller with a callback that receives the open interface from your directive. Your controller captures the interface and uses it in the script, but it wants it. Simple and can be implemented in any existing directive.

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

A lot more complicated, but a great picture ...

2.
If you want to create a directive that also has a programmable interface, I suggest implementing the core of the directive as a provider. Then you can implement your directive based on the provider, and in cases where you want to access the same functionality completely through a script, you can directly work with the provider by entering it into your controller.

This is an implementation strategy followed by ngDialog

In addition, since you are creating a confirmation dialog, you will find this template useful, since your public method can return a promise that can be allowed or rejected by your dialog box, which allows your controller to respond based on the promise.

PLNKR DEMO

 <!DOCTYPE html> <html> <head> <script data-require=" angular.js@ *" 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> 
+7
source

You can observe the change in the scope property in your directive.

For example, add confirm-show-when

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

Add it to your directive definition

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

And in your controller, just set showConfirmDialog to true when you want to show it.

 // 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; } 
0
source

Source: https://habr.com/ru/post/1205871/


All Articles