Im using angular 1.x
and I have created a custom directive called slider as following code.
I'm trying to transclude
the content of slider directive in order to modify it inside the transclude function. But the problem is clone is not giving a collection of .slide elements. Instead it gives a comment which relates to ng-repeat
. I cannot get the compiled output of ng-repeat
which should be a collection of .slide divs.
I want to know how to access the result of ng-repeat
inside transclude
function so that I can successfully call scope.showCurrent.
Now what happens is, $('.slide')
call inside scope.showCurrent()
doesnt catch any .slide
divs because at the time of call there are no .slide
elements. But if ng-repeat
provided its compiled html inside transclude function, $('.slide')
will catch divs.
app.directive('slider', function ($compile) {
return {
restrict: 'EA',
priority: 1200,
scope: true,
controller: function ($scope) {
$scope.slider = { currentIndex: 0 };
},
transclude:'element',
link: function (scope, el, attrs, ctrl, transclude) {
scope.showCurrent = function (currentIndex) {
console.log('x')
$('.slide').hide();
$('.slide').eq(currentIndex).show();
}
scope.$watch('slider.currentIndex', function (val) {
console.log('tst');
scope.showCurrent(val);
});
transclude(scope, function (clone) {
el.after(clone);
scope.showCurrent(scope.slider.currentIndex);
})
},
}
});
Following is the html usage of this directive.
<slider>
<div ng-repeat="slide in slides" class="slide">
<div>Image {{img}}</div>
<img ng-src="img"/>
</div>
</slider>
Here is my plunk https://plnkr.co/edit/m7YJBNuDjeLPaKkUYK5S?p=preview
You don't get .slide divs
because at the time your code inside transclude
is being executed:
el.after(clone);
scope.showCurrent(scope.slider.currentIndex);
the linking functions of the inner content, particularly ng-repeat
's linking function, has not been executed yet. It's inside this linking function a watcher is added for the slides
.
Even if you wait until the linking functions get executed, as in here:
transclude(scope, function (clone) {
el.after(clone);
scope.showCurrent(scope.slider.currentIndex);
})
// here the linking functions of the `clone` have already been executed
.slide divs
are still not available until the first digest loop runs.
After your update
You definitely don't need this part here
transclude(scope, function (clone) {
el.after(clone);
scope.showCurrent(scope.slider.currentIndex);
})
because it will be different clone
that the one processed by ng-transclude
and ng-transclude
will take care of compiling and linking the content. You have to wait until digest loops runs and ng-repeat renders the div .slider
elements. For that, use $timeout
:
$timeout(function() {
scope.showCurrent(scope.slider.currentIndex);
});