Search code examples
javascriptangularjsangular-directive

How can I augment a directive's link function with angular's decorator pattern?


I'm working on an Angular library and looking for a way to extend a directive using the decorator pattern:

angular.module('myApp', []).decorator('originaldirectiveDirective', [
  '$delegate', function($delegate) {

    var originalLinkFn;
    originalLinkFn = $delegate[0].link;

    return $delegate;
  }
]);

What would be the best way to augment the original directive using this pattern? (Example usage: to have additional watches or extra event listeners on the directive without modifying it's code directly).


Solution

  • You can modify or extend directive's controller quite easily. If it's link you are looking for (as in your example), it's not that much harder. Just modify directive's compile function in config phase.

    For example:

    HTML template

    <body>
      <my-directive></my-directive>
    </body>
    

    JavaScript

    angular.module('app', [])
    
      .config(function($provide) {
        $provide.decorator('myDirectiveDirective', function($delegate) {
          var directive = $delegate[0];
    
          directive.compile = function() {
            return function(scope) {
              directive.link.apply(this, arguments);
              scope.$watch('value', function() {
                console.log('value', scope.value);
              });
            };
          };
    
          return $delegate;
        });
      }) 
    
      .directive('myDirective', function() {
        return {
          restrict: 'E',
          link: function(scope) {
            scope.value = 0; 
          },
          template: '<input type="number" ng-model="value">'
        };
      });
    

    Now you have decorated myDirective to log value when ever it has changed.

    Related plunker here https://plnkr.co/edit/mDYxKj