Reputation: 152294
I have created a custom directive with method defined:
app.directive('modal', function() {
return {
restrict: 'E',
template: '<div class="modal" ng-show="visible">modal box</div>',
scope: {
ngModel: '='
},
link: function(scope, element, attrs) {
scope.visible = false;
scope.show = function () {
this.visible = true;
};
scope.close = function () {
this.visible = false;
};
}
};
});
I'm using it like:
<button ng-click="modal.show()">Show modal</button>
<modal></modal>
However I cannot access this modal
directive in the same scope.
I've tried with defined id
attribute, like:
<button ng-click="myModal.show()">Show modal</button>
<modal id="myModal"></modal>
Is it even possible to access directive scope this way ?
Or better way would be do it using $rootScope
or broadcasting events ?
I would like to not define this directive in controller - controller should not know about its existence.
Upvotes: 0
Views: 77
Reputation: 555
Your view might be like below:
<button ng-click="showModal()">Show modal</button>
<modal></modal>
You can put your methods to the $rootScope apart from the isolated scope. Only the template uses it's isolated scope and variables defined on it.
Here is a modified example:
app.directive('modal', function ($rootScope) {
return {
restrict: 'E',
template: '<div ng-show="visible">modal box</div>',
scope: {},
link: function (scope, element, attrs) {
scope.visible = false;
$rootScope.showModal = function () {
console.log("showModal");
scope.visible = true;
};
$rootScope.closeModal = function () {
console.log("closeModal");
scope.visible = false;
};
}
};
});
Upvotes: 0
Reputation: 130191
You found a problem in your architecture. It's true that there are workarounds but they only make the problem more complicated.
If you look for a stable solution, check out the code for $modal
in Angular Bootstrap. You will see they have $modal
as a service.
The reasons are (for example) the following:
Upvotes: 1
Reputation:
I would go with events:
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.showModal = function(){
$scope.$parent.$broadcast("show-modal");
};
$scope.hideModal = function(){
$scope.$parent.$broadcast("hide-modal");
};
}
myApp.directive('modal', function() {
return {
restrict: 'E',
template: '<div class="modal" ng-show="visible">modal box</div>',
link: function(scope, element, attrs) {
scope.visible = false;
scope.$on('show-modal', function(){
scope.visible = true;
});
scope.$on('hide-modal', function(){
scope.visible = false;
});
}
};
})
Basically: broadcast an event (either 'show' or 'hide') from your controller, catch it inside the directive and do your logic.
And your html template:
<div ng-controller="MyCtrl" ng-app="myApp">
<button ng-click="showModal()">Show modal</button>
<br/>
<button ng-click="hideModal()">Hide modal</button>
<modal></modal>
</div>
Upvotes: 0
Reputation: 369
Parent controllers have access to their child directives' scopes.
Here I've created a small example to illustrate what I'm saying. Unless you have the scope attribute in your directive, it will use its parent's scope.
Upvotes: 0