Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trigger a function in a child directive from it's parent [angularJS]

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 () {...};
        }
    })
like image 303
Armeen Harwood Avatar asked May 15 '26 22:05

Armeen Harwood


2 Answers

This 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();
  }
like image 136
pixelbits Avatar answered May 17 '26 12:05

pixelbits


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
      });
like image 36
Scott Avatar answered May 17 '26 13:05

Scott