This question is more complex than it might seem, so let it break.
What you are building is a directive that accepts a partial template - <div item-row item="item" /> - and that uses (or associates with region c) with an internal variable - item is not user-defined in the external volume; its value is determined by your directive, and your user "discovers" it by reading the documentation of your directive. I usually call these "magic" variables the $ prefix, for example. $item .
Step 1
Instead of passing the template as HTML-as-string via attribute binding, pass it as content and translate that content. Transcluding allows you to associate broadcast content with an arbitrary scope:
<foo> <div>my item is: {{$item}}</div> </foo>
.directive("foo", function(){ return { scope: {}, transclude: true, template: "<h1>I am foo</h1><placeholder></placeholder>", link: function(scope, element, attrs, ctrls, transclude){ scope.$item = "magic variable"; transclude(scope, function(clonedContent){ element.find("placeholder").replaceWith(clonedContent); }); } }; });
The above will post the template <div>my item is: {{$item}}</div> (there can be any template you specify) where the foo directive solves and will refer to the area that has $item .
Step 2
But the added complexity of your directive is that it uses ng-repeat , which itself accepts the template, and the template that your directive receives should be used as the ng-repeat template.
Using only the above approach, this will not work, since by the time the link is executed ng-repeat will already broadcast its own content before you have the opportunity to apply yours.
One way to access this is to manually $compile the foo template instead of using the template property. Before compilation, we will have the opportunity to place the required template where necessary:
.directive("foo", function($compile){ return { scope: {}, transclude: true, link: function(scope, element, attrs, ctrls, transclude){ scope.items = [1, 2, 3, 4]; var template = '<h1>I am foo</h1>\ <div ng-repeat="$item in items">\ <placeholder></placeholder>\ </div>'; var templateEl = angular.element(template); transclude(scope, function(clonedContent){ templateEl.find("placeholder").replaceWith(clonedContent); $compile(templateEl)(scope, function(clonedTemplate){ element.append(clonedTemplate); }); }); } }; });
Demo