3

I have several directives that use the same link function. (The link function adds some extra state and html depending on the use case.) So I declared this as follows:

function common_linkfunc(){...}

var Directive_1 = function($scope, etc) {
   return {restrict:"E", ...
           link: common_linkfunc,
           controller: function($scope, etc) {...}
   };
}
Directive_1.$injects = ["$scope", "etc"];
angular.module("module").directive("D1", Directive_1)...;

First change was when link function required $compile. Next I need to add $templateCache and my question is how can I do this systematically?

My first approach was to rewrite common_linkfunc as

function foo($compile, $templateCache) {
    return common_linkfunc($compile, $templateCache) {...}
}

and then use this in every directive:

... link: foo($compile, $templateCache), ...

But this is copy-and-paste! Is there an easier and less error prone way to do the same?

1 Answer 1

2

Regardless of the solution, you'll need to pass some argument to your common link function, because Angular won't inject anything into it for you. That being said, I can think of two different approaches:

1) Use arguments

app.directive('foo', function($http, $timeout) {
  return {
    restrict: 'E', 
    link: linkFn1.apply(null, arguments)
  }
});

function linkFn1($http, $timeout) {
  return function(scope, element, attrs) {
    // ...
  };
}

The downside here is that the order of the arguments in the directive function matters. If some other directive uses a different order, the code won't work properly.

2) Use $injector

app.directive('bar', function($injector) {
  return {
    restrict: 'E', 
    link: linkFn2($injector)
  }
});

function linkFn2($injector) {
  var $http = $injector.get('$http'),
      $timeout = $injector.get('$timeout');

  return function(scope, element, attrs) {
    // ...
  };
}

Working Plunker

Sign up to request clarification or add additional context in comments.

1 Comment

thanks - just learned something new! I think $injector is more flexible and much easier to adapt to changing needs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.