Interaction between nested directives
AngularJS provides a useful structure that allows you to build channels of communication between directive siblings (within the same HTML element) or parents in the same DOM ancestry without having to rely on AngularJS events.
Getting ready
For this recipe, suppose that your application template includes the following:
(index.html) <div ng-app="myApp"> <div parent-directive> <div child-directive sibling-directive> </div> </div> </div>
How to do it…
Inter-directive communication is accomplished with the require
attribute, as follows:
return {
require: ['^parentDirective', '^siblingDirective'],
link: function (scope, el, attrs, ctrls) {
$log.log(ctrls);
// logs array of in-order required controller objects
}
};
Using the stringified directive names passed through require
, AngularJS will examine the current and parent HTML elements that match the directive names. The controller objects of these directives will be returned in an array as the ctrls
parameter in the original directive's link
function.
These directives can expose methods as follows:
(app.js) angular.module('myApp', []) .directive('parentDirective', function ($log) { return { controller: function () { this.identify = function () { $log.log('Parent!'); }; } }; }) .directive('siblingDirective', function ($log) { return { controller: function () { this.identify = function () { $log.log('Sibling!'); }; } }; }) .directive('childDirective', function ($log) { return { require: ['^parentDirective', '^siblingDirective'], link: function (scope, el, attrs, ctrls) { ctrls[0].identify(); // Parent! ctrls[1].identify(); // Sibling! } }; });
Tip
JSFiddle: http://jsfiddle.net/msfrisbie/Lnxeyj60/
How it works…
The childDirective
fetches the requested controllers and passes them to the link
function, which can use them as regular JavaScript objects. The order in which directives are defined is not important, but the controller objects will be returned in the order in which they are requested.
See also
- The Optional nested directive controllers recipe demonstrates how to handle a scenario where parent or sibling controllers might not be present