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;