I have the following directive for showing a popup to confirm an execution of a function on click.
Now i would like to use it within my controller to show a popup if the properties of an object has been changed and the user wants to change the location without saving the object before. Is that 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 that:
<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>
You simply define a “callback” function in the controller and pass it to the directive (using the '&' symbol in the isolated scope definition). It's then trivial for the directive to invoke the function, which calls into the controller.
For calling directive method from component, you could use ViewChild decorator to locate directive instance on the page. Then by using the same you could access directive all props.
The button is then calling $scope.directiveFn () in your controller which has been mapped to scope.updateMap () in your directive. Show activity on this post. Show activity on this post. Just call the directive function from your controller/template and initialise that function in your directive using two-way binding symbol
Much like you create controllers and services, you can create your own directives for AngularJS to use. When AngularJS bootstrapsyour application, the HTML compilertraverses the DOM matching directives against the DOM elements. What does it mean to "compile" an HTML template?
For AngularJS, "compilation" means attaching directives to the HTML to make it interactive. The reason we use the term "compile" is that the recursive process of attaching directives mirrors the process of compiling source code in compiled programming languages. Matching Directives
Best Practice:Comment directives were commonly used in places where the DOM API limits the ability to create directives that spanned multiple elements (e.g. inside <table>elements). AngularJS 1.2 introduces ng-repeat-startand ng-repeat-endas a better solution to this problem.
N0-$watch solutions:
1.
Provide your controller with a callback which receives an exposed interface from your directive. Your controller grabs the interface and uses it in script however it desires. Simple and can be implemented on 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}});
}
}
});
Much more complicated but an excellent pattern...
2.
If you wish to make a directive which also has a programmable interface then I suggest implementing the core of the directive as a provider. You could then implement your directive based on the provider and in cases where you wanted to access the same functionality completely through script, you could operate directly on the provider by injecting it into your controller.
This is the implementation strategy followed by ngDialog
Also, as you are are creating a confirmation dialog you would find this pattern useful as your open method could return a promise which can be resolved or rejected by your dialog, allowing 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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With