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.
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>
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/