Skip to content

Instantly share code, notes, and snippets.

@alexcastillo
Last active March 3, 2016 02:10
Show Gist options
  • Save alexcastillo/7b90b21beaa242a903b1 to your computer and use it in GitHub Desktop.
Save alexcastillo/7b90b21beaa242a903b1 to your computer and use it in GitHub Desktop.
Hacking AngularJS in oder to broadcast a custom event for directives
/**
* AngularJS hack - This way we can get and decorate all custom directives
* in order to broadcast a custom directive events: $directiveAdd
**/
// This is where all the custom directives will be stored
var $directives = [];
var originalModule = angular.module;
angular.module = function () {
var module = originalModule.apply(this, arguments);
var originalDirective = module.directive;
module.directive = function(directiveName, directiveFactory) {
var originalDirectiveFactory = angular.isFunction(directiveFactory) ?
directiveFactory : directiveFactory[directiveFactory.length - 1];
// The only way to get the DDO without messing with directives is with a try block
try {
var directive = angular.copy(originalDirectiveFactory)();
directive.directiveName = directiveName;
$directives.push(directive);
} catch (e) {
// Nothing needs to happen here
}
return originalDirective.apply(this, arguments);
};
module.config(['$provide','$injector', function ($provide, $injector) {
angular.forEach($directives, function ($directive) {
var dirProvider = $directive.directiveName + 'Directive';
// This way we can check if the provider exists (avoids errors in angular 1.2)
if ($injector.has(dirProvider)) {
// For each directive registered, we decorate and extend the compile function
$provide.decorator(dirProvider, ['$delegate', '$rootScope', '$timeout', function ($delegate, $rootScope, $timeout) {
var directive = $delegate[0];
var compile = directive.compile;
directive.compile = function(tElement, tAttrs) {
var link = compile ? compile.apply(this, arguments): false;
return function(scope, element, attrs) {
var linkArgs = arguments;
// Need to trigger a digest cycle
$timeout(function () {
if (link) link.apply(this, linkArgs);
});
// And finally we can broadcast our custom directive add event
$rootScope.$broadcast('$directiveAdd', directive, scope);
};
};
return $delegate;
}]);
}
});
}]);
return module;
};
/* End of hack */
@enricolucia
Copy link

Can I suggest you to rewrite this as the follow?
As the way it is as the moment jshint prompts error on thisl

/*global angular*/
/**
 * AngularJS hack - This way we can get and decorate all custom directives 
 * in order to broadcast a custom directive events: $directiveAdd
 **/
// This is where all the custom directives will be stored

var $directives = [];
var originalModule = angular.module;
angular.module = function () {
  var module = originalModule.apply(this, arguments);
  var originalDirective = module.directive;
  module.directive = function(directiveName, directiveFactory) {
    var originalDirectiveFactory = angular.isFunction(directiveFactory) ? 
    directiveFactory : directiveFactory[directiveFactory.length - 1];
    // The only way to get the DDO without messing with directives is with a try block
    try {
      var directive = angular.copy(originalDirectiveFactory)();
      directive.directiveName = directiveName;
      $directives.push(directive);
    } catch (e) { 
      // Nothing needs to happen here 
    }
    return originalDirective.apply(this, arguments);
  };
  module.config(['$provide','$injector', function ($provide, $injector) {
    angular.forEach($directives, function ($directive) {
      var dirProvider = $directive.directiveName + 'Directive';
      // This way we can check if the provider exists (avoids errors in angular 1.2)
      if ($injector.has(dirProvider)) {
        // For each directive registered, we decorate and extend the compile function
        $provide.decorator(dirProvider, ['$delegate', '$rootScope', '$timeout', function ($delegate, $rootScope, $timeout) {
          var directive = $delegate[0];
          var compile = directive.compile;
          directive.compile = function() { 
            var link = compile ? compile.apply(this, arguments): false;
            return function(scope) {
              // Need to trigger a digest cycle
              $timeout(function () {
                if (link) {link.apply(this, arguments);}
              });
              // And finally we can broadcast our custom directive add event
              $rootScope.$broadcast('$directiveAdd', directive, scope);
            };
          };
          return $delegate;
        }]);
      }
    });
  }]);
  return module;
};
/* End of hack */

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment