I created a component search-context, which works well. It's configurable and it does what it's supposed to do.
<search-context context-name="Groups"
compare-columns="['displayName']"
search-manager="$ctrl"
query-url="/group/search/{{contextId}}"
icon="fa fa-users"
on-resolve-item-url="resolveItemUrl(row)"></search-context>
Here it is in action, standalone.
There are various other search contexts, and I'd like to create a search-manager component such that I can write markup like this:
<search-manager>
<search-context context-name="Devices"
compare-columns="['displayName']"
search-manager="$ctrl"
query-url="/device/search/{{contextId}}"
icon="fa fa-laptop"></search-context>
<search-context context-name="Groups"
compare-columns="['displayName']"
search-manager="$ctrl"
query-url="/group/search/{{contextId}}"
icon="fa fa-users"
on-resolve-item-url="resolveGroupEditUrl(row)"></search-context>
</search-manager>
The general plan is for search-context to check whether it has a search-manager and if so suppress its own input/button controls, and the search-manager will supply input controls and supply the search term to the search contexts.
The examples in the AngularJS component documentation demonstrate dynamic child controls using ng-repeat in the control template, but it's not clear how to set things up to handle explicit markup such as I propose. If at all possible I'd prefer not to need to explicitly specify the search-manager="$ctrl" parent reference.
How does one go about this and what are the supporting topics one must research and understand? Just the key concept names would be a big help but an overview and a further-reading list would be awesome.
My first attempt at the template for search-manager looks like this
<div>
<div class="panel-heading">
<h3 class="panel-title">Search</h3>
<div class="input-group">
<input class="form-control" ng-model="$ctrl.term" />
<span class="input-group-btn" ng-click="$ctrl.search()">
<button class="btn btn-default">
<i class="fa fa-search"></i>
</button>
</span>
</div>
</div>
<div class="panel-body">
<ng-transclude></ng-transclude>
</div>
</div>
The code looks like this
function SearchManagerController($scope, $element, $attrs, $http) {
var ctrl = this;
ctrl.searchContext = [];
ctrl.registerSearchContext = function (searchContext) {
ctrl.searchContext.push(searchContext);
}
ctrl.search = function () {
ctrl.searchContext.forEach(function (searchContext) {
searchContext.search(ctrl.term);
});
};
}
angular.module("app").component("searchManager", {
templateUrl: "/app/components/search-manager.html",
controller: SearchManagerController,
transclude: true,
bindings: {
term: "@"
}
});
The child components are transcluded but they need a reference to the search-manager component, and $ctrl is not in scope.
How do we get a reference to the parent?

To obtain a reference to the parent all you need to do is
requirethe parent in thesearch-contextdeclaration. The double caret prefix means to search the parents. Single caret starts with the current object which will work but is slightly less efficient. The question mark means don't barf if you can't find it, just return undefined. This is necessary when the component may not always be parented by a search manager.But what if you need the parent to have references to the children?
In the
SearchContextControllerwe implement the$onInitlifecycle event handler.registerSearchContextis a method defined in the parent's controller for this purpose. The implementation essentially pushes each registered control into an array property we define on its scope, and then methods of the parent can enumerate the children.For a directive this
requiretrick is expressed slightly differently. You must declare the propertysearchManagerCtrlin the directive scope, and supply the expression directly as the value of require.You must also supply a
linkfunction. One of the parameters of alinkfunction iscontrollerand a reference tosearchManagerwill be passed in this parameter, at which point you can assign it to a property of the directive scope. The$onInitlifecycle event is still available for registering with the search manager, but refers to$scoperather thanctrl.