So I totally do this in reverse all the time when using the directive property require: '^ParentCtrl'
inside the child directive. Using require to then call the parent function; however, I need to do this in reverse.
Question:
How do I trigger FROM a parent directive the execution of a function IN a child directive.
Note:
1. Child Directive has no function is inside a link:
2. essentially I want a reverse require.
Parent Directive:
'use strict';
angular.module('carouselApp')
.directive('waCarousel', function() {
return {
templateUrl: 'views/carousel/wa.carousel.html',
controller: function($scope) {
var self = this;
// this function is being called based on how many pages there are
self.carouselElLoaded = function(result) {
var count = 1;
Carousel.params.pageRenderedLength += count;
//when all the pages are loaded
if (Carousel.params.pageRenderedLength === Carousel.params.pageLength) {
Carousel.params.carouselReady = true;
// !!!!!!!! Trigger will go here!!!!!!!!!//
ChildCtrl.drawHotspots(); // (**for placement only**)
} else {
Carousel.params.carouselReady = false;
}
};
}
}
})
Child Directive:
'use strict';
angular.module('carouselApp')
.directive('waHotspots', function() {
return {
require: '^waCarousel',
link: function (scope, element, attrs, ctrl) {
//call this directive based on how
scope.drawHotspots = function () {...};
}
})
So I totally do this in reverse all the time when using the directive property require: '^ParentCtrl'
inside the child directive. Using require to then call the parent function; however, I need to do this in reverse.
Question:
How do I trigger FROM a parent directive the execution of a function IN a child directive.
Note:
1. Child Directive has no function is inside a link:
2. essentially I want a reverse require.
Parent Directive:
'use strict';
angular.module('carouselApp')
.directive('waCarousel', function() {
return {
templateUrl: 'views/carousel/wa.carousel.html',
controller: function($scope) {
var self = this;
// this function is being called based on how many pages there are
self.carouselElLoaded = function(result) {
var count = 1;
Carousel.params.pageRenderedLength += count;
//when all the pages are loaded
if (Carousel.params.pageRenderedLength === Carousel.params.pageLength) {
Carousel.params.carouselReady = true;
// !!!!!!!! Trigger will go here!!!!!!!!!//
ChildCtrl.drawHotspots(); // (**for placement only**)
} else {
Carousel.params.carouselReady = false;
}
};
}
}
})
Child Directive:
'use strict';
angular.module('carouselApp')
.directive('waHotspots', function() {
return {
require: '^waCarousel',
link: function (scope, element, attrs, ctrl) {
//call this directive based on how
scope.drawHotspots = function () {...};
}
})
Share
Improve this question
asked Dec 30, 2014 at 1:28
John AbrahamJohn Abraham
18.8k36 gold badges132 silver badges240 bronze badges
3 Answers
Reset to default 5This is possible by having the parent controller talk to the child controller through a well defined API, that you create. The idea is that you want to maintain loose coupling between the parent and the child directive by having each respective controller knowing as little about each other as possible, but still have enough knowledge to get the job done.
To achieve this, require the parent directive from the child directive, and let the child directive register itself with parent's controller:
Child directive:
require: '^parentDirective',
controller: function(){
this.someFunc = function() {...}
},
link: function(scope,element,attr, parentCtrl){
parentCtrl.register(element);
}
Then in your parent directive, implement the register function, and get the child's controller, and call the child's function when needed:
Parent directive:
controller: function(){
var childCtrl = undefined;
this.register = function (element) {
childCtrl = element.controller();
}
this.callChildFunc = function (){
childCtrl.someFunc();
}
},
link: function (scope,element){
var ctrl = element.controller();
ctrl.callChildFunc();
}
You could always trigger it via a $watch. Just pass in the parent scope value that you want to watch and change it's value.
Parent:
$scope.drawHotspots = false;
Template:
waHotspots the-trigger="drawHotspots"....
Child Directive:
localTrigger: '@' // Receive the value to watch
scope.$watch('localTrigger',function() {
// call drawHotspots if value is set to true
});
Its on old topic but I came here today so might others ...
I think the best approche is to use a Service
angular.module('App').service('SomeService', [SomeService]);
Then inject the service into both the parent and child ...
controller : ['$rootScope', '$scope','SomeService', SomeDirectiveController],
Use the service to talk to each other ...
In their controllers SomeService.setParent(this)
and SomeService.setChild(this)
Service would have a field to hold the references :
this.parentCtrl = null;
this.childCtrl = null;//or [] in-case you have multiple childs!
Somewhere in the parent : SomeService.childCtrl.someFunctionInChild()
Or if you want a restricted access , in service make the fields private :
var parentCtrl = null;
var childCtrl = null;//or [] in-case you have multiple childs of the same type!
this.callUserFunc = function(param){childCtrl.someFunctionInChild(param)};
And Somewhere in the parent : SomeService.callUserFunc(myparam)