Search code examples
javascriptangularjsfunctionangularjs-directiverootscope

Call function from directive in $rootScope - AngularJS


What I want to do:

I'm trying to create a function within a directive that can be called from the $rootScope.


The Problem:

It seems to only be working on the last item in the DOM which has this directive. I'm guessing that what's happening is rootScope.myFunction gets overwritten each time this directive runs.


The Question:

How can I create one function in the $rootScope which, when called, runs the internal function for each directive instead of just the last one?


The Relevant Code:

(function() {
  angular.module('home')
    .directive('closeBar', closeBar);

  closeBar.$inject = ['$rootScope', '$window'];
  function closeBar(rootScope, window) {
    return {
      scope: true,
      restrict: 'A',
      link: function(scope, element, attrs) {

        var myFunction = function() {
          // do stuff
        };

        myFunction();

        rootScope.myFunction = function() {
          myFunction();
        };
      }
    };
  }
})();

Then in a different script, I want to call:

rootScope.myFunction();

Note, I'm not allowed to share actual code from the project I'm working on so this is a more general question not tied to a specific use case.


Solution

  • A simple solution would be to create a special function in your rootScope that accepts functions as an argument, and pushes it into an array, and you will be able to invoke that function later which will call all the registered functions.

     angular.module('myApp').run(['$rootScope', function($root) {
          var functionsToCall = [];
          $root.registerDirectiveFunction = function(fn, context) {
              context = context || window;
              functionsToCall.push({fn: fn, context: context});
          }
          $root.myFunction = function(args) {
              functionsToCall.forEach(function(fnObj) {
                  fnObj.fn.apply(fnObj.context,args);
              });
          }
     }
    

    And in your directive:

     link: function($scope, $el, $attr) {
          function myFunct() {
          }
          $scope.$root.registerDirectiveFunction(myFunct, $scope);
          //call it if you want
          $scope.$root.myFunction();
     }
    

    This should cover your scenario.