StackOverflow_23647677: angular-transcluded-directive-as-sibling-scope-incompatible-with-child-directive

Illustration of answer to http://stackoverflow.com/questions/23647677/angular-transcluded-directive-as-sibling-scope-incompatible-with-child-directive.

by ExpertSystem

HTML

<script src="http://code.angularjs.org/1.2.16/angular.min.js"></script>
<div ng-controller="myCtrl">
    <div price-chart>
        <div volume-indicator></div>
    </div>
</div>

JavaScript

var app = angular.module('myApp', []);

/* Controllers */
app.controller('myCtrl', function ($scope) {});
app.controller('priceChartCtrl', function () {
    var indicators = [];
    this.addIndicator = function (volumeIndicatorCtrl) {
        indicators.push({id: volumeIndicatorCtrl.getID()});
    };
    this.hasIndicator = function (id) {
        return indicators.some(function (ind) {
            return ind.id === id;
        });
    };
});
app.controller('volumeIndicatorCtrl', function () {
    var id = Math.ceil(Math.random() * 1000);
    this.getID = function () {
        return id;
    };
});

/* Directives */
app.directive('priceChart', function () {
    return {
        restrict: 'EA',
        transclude: true,
        controller: 'priceChartCtrl',
        template: '<div ng-transclude></div>'
    };
});
app.directive('volumeIndicator', function () {
    return {
        restrict: 'EA',
        require: ['^priceChart', 'volumeIndicator'],
        controller: 'volumeIndicatorCtrl',
        template: [
            '<div>',
            '    I am a volume indicator with ID: {{indicatorID}}<br />',
            '    Am I registered with my wrapping price-chart ?',
            '    I most definitely am {{isRegistered(indicatorID)?\'\':\'not \'}}!',
            '</div>',
            ''].join('\n'),
        link: {
            pre: function preLink(scope, elem, attrs, ctrls) {
                var priceChartCtrl = ctrls[0];
                var volumeIndicatorCtrl = ctrls[1];
                priceChartCtrl.addIndicator(volumeIndicatorCtrl);

                scope.indicatorID = volumeIndicatorCtrl.getID();
                scope.isRegistered = function (indicatorID) {
                    return priceChartCtrl.hasIndicator(indicatorID);
                };
            }
        }
    };    
});