AngularJS - Directive Communication

The initial setup:

<div ng-app="app">
  <country>
    <state> 
      <city>

      </city>
    </state>
  </country>
</div>
var app = angular.module("app",[]);

app.directive("country", function () {
  return {
    restrict: "E",
    controller: function () {
      this.makeAnnouncement = function (message) { 
        console.log("Country says: " + message);
      };
    }
  };
});
app.directive("state", function () {
  return {
    restrict: "E"
  };
});
app.directive("city", function () {
  return {
    restrict: "E",
    require: "^country",
    link: function (scope, element, attrs, countryCtrl) {
      countryCtrl.makeAnnouncement("This city rocks");
    }
  };
});

If one knows there is a hierarchical relationship between nested directives, it is possible to communicate between them using controllers. With their respective directives, a parent directive can expose something like the makeAnnouncement() method, and have it passed down to a child directive. Here, we can inject the country directive controller into the linking function of the city directive. This is accomplished by matching the require naming scheme to the parent directive name. With this, the controller of the parent directive is available for use in the child directive. This ‘inheritance’ of the controller works invariant of ancestral distance.

This controller inheritance is not limited to a single controller instance:

});
app.directive("state", function () {
  return {
    restrict: "E",
    controller: function () {
      this.makeLaw = function (law) {
        console.log("Law: " + law);
      };
    }
  };
});
app.directive("city", function () {
  return {
    restrict: "E",
    require: ["^country","^state"],
    link: function (scope, element, attrs, ctrls) {
      ctrls[0].makeAnnouncement("This city rocks");
      ctrls[1].makeLaw("Jump higher");
    }
  };
});