After reading the docs about the transclude option, I was going to write something (see below), but after playing around with codepen, I got even more confused. I think, what you are trying to do is rather difficult.
A quick (and maybe dirty) solution would be to use a service for your counter. https://codepen.io/anon/pen/vxwpxo
app.directive('loader', function(myCounter) {
return {
restrict: 'E',
replace: true,
scope: {},
template: '<div>{{opacity}}</div>',
link: function(scope) {
scope.opacity = myCounter.get();
}
};
});
app.factory('myCounter', function() {
var counter = 0;
return {
get: function() {
return counter++;
}
};
});
Previous thoughts:
The transclude option changes the way scopes are nested. It makes it so that the contents of a transcluded directive have whatever scope is outside the directive, rather than whatever scope is on the inside. In doing so, it gives the contents access to the outside scope.
Note that if the directive did not create its own scope, then scope in scope.name = 'Jeff'; would reference the outside scope and we would see Jeff in the output.
https://code.angularjs.org/1.4.6/docs/guide/directive
I don't know, if have a controller outside your directives where counter is defined. If yes, the code in your directive controller won't change the value of counter (if I've understood the docs correctly). If no, then each directive will instantiate its own counter, and because it hasn't been set yet if (!$scope.counter) will always be true. And it's behaving differently if the directive has an isolated scope or not.
I'm getting confused!
loader | testresults into what html? (Sorry, I don't know pug). But I think, now I understand what you are trying to achieve.