diff --git a/docs/content/guide/directive.ngdoc b/docs/content/guide/directive.ngdoc
index 704dd48357c5..0183b1d7a9fb 100644
--- a/docs/content/guide/directive.ngdoc
+++ b/docs/content/guide/directive.ngdoc
@@ -893,11 +893,10 @@ option. Just like `ngController`, this option attaches a controller to the templ
Looking back at `myPane`'s definition, notice the last argument in its `link` function: `tabsCtrl`.
When a directive requires a controller, it receives that controller as the fourth argument of its
-`link` function. Taking advantage of this, `myPane` can call the `addPane` function of `myTabs`.
+`link` function or will be injected in your controller as $requiredControllers. Taking advantage of this, `myPane` can call the `addPane` function of `myTabs`.
Savvy readers may be wondering what the difference is between `link` and `controller`.
-The basic difference is that `controller` can expose an API, and `link` functions can interact with
-controllers using `require`.
+The basic difference is that `controller` can expose an API, and `link` functions not. They both can interact with controllers using `require`.
**Best Practice:** use `controller` when you want to expose an API to other directives.
diff --git a/src/ng/compile.js b/src/ng/compile.js
index 193dff7ad19d..4e1959465571 100644
--- a/src/ng/compile.js
+++ b/src/ng/compile.js
@@ -1477,11 +1477,29 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
transcludeFn = boundTranscludeFn && controllersBoundTransclude;
if (controllerDirectives) {
forEach(controllerDirectives, function(directive) {
+ // github issue #5893 Add ability to inject required controllers
+ // into the controller function
+ var requiredControllers;
+ if (directive.require && directive.require !== directive.name) {
+ // the directive requires its own controller. this would make an error
+ // this does not prevent require: "^sameDirective"
+ var requiredControllersCopy = angular.copy(directive.require);
+ if (angular.isArray(requiredControllersCopy)) {
+ var indexOfSelf = requiredControllersCopy.indexOf(directive.name);
+ if (indexOfSelf !== -1) {
+ requiredControllersCopy.splice(indexOfSelf, 1);
+ }
+ }
+ requiredControllers = requiredControllersCopy
+ && getControllers(requiredControllersCopy, $element, elementControllers);
+ }
+
var locals = {
$scope: directive === newIsolateScopeDirective || directive.$$isolateScope ? isolateScope : scope,
$element: $element,
$attrs: attrs,
- $transclude: transcludeFn
+ $transclude: transcludeFn,
+ $requiredControllers: requiredControllers
}, controllerInstance;
controller = directive.controller;