Reputation: 57
I have a simple Carousel example. The example on Plnkr shows what I do in my application. I have to change the slides in my application. When I set the active slide after I change slides it goes to that slide and then slides out into oblivion or it goes to the first slide. How can I solve this problem? So that after making new slides I can go to the right slide?
http://plnkr.co/edit/PJg9U4HZ1k5aSTSvbl3k?p=preview
angular.module('plunker', ['ui.bootstrap', 'ngTouch']);
function CarouselDemoCtrl($scope) {
$scope.genderPerson = "men";
$scope.myInterval = -1;
$scope.slides = [];
$scope.$watch("genderPerson", function( newValue, oldValue ) {
$scope.MakeSlides();
});
$scope.MakeSlides = function() {
var newSlides = [];
for ( var i = 0; i < 10; i++ ) {
newSlides[i] = { image: 'http://api.randomuser.me/portraits/' + $scope.genderPerson + '/' + i + '.jpg' };
}
$scope.slides = newSlides;
if ( $scope.slides[6] ) {
$scope.slides[6].active=true;
}
}
}
Upvotes: 0
Views: 3389
Reputation: 113
I just struggled with this problem. Here's my overly technical hack totally legit solution:
addSlide
method.directive('onCarouselChange', function ($animate, $parse) {
return {
require: 'carousel',
link: function (scope, element, attrs, carouselCtrl) {
var origAdd = carouselCtrl.addSlide;
carouselCtrl.addSlide = function(slide, element) {
origAdd.apply(this, arguments);
$animate.on('enter', element, function (elem, phase) {
if (phase === 'close') {
scope.$emit('carouselEntered');
}
});
};
}
};
})
This will emit an event when the carousel's ngRepeat has finished parsing its new elements.
<carousel interval="myInterval" on-carousel-change>
Add an event listener to the function where you add the elements, and set the active slide on its callback
$scope.MakeSlides = function() {
var newSlides = [];
for ( var i = 0; i < 10; i++ ) {
newSlides[i] = { image: 'http://api.randomuser.me/portraits/' + $scope.genderPerson + '/' + i + '.jpg' };
}
$scope.slides = newSlides;
var dereg = $scope.$on('carouselEntered', function(event, data) {
if ($scope.slides[6]) {
$timeout(function () {
$scope.slides[6].active=true;
});
dereg();
}
});
}
All of this is possible thanks to the magic of $animate's events.
Upvotes: 0
Reputation: 6629
Looks like there is a race condition, if I wrap the active slide set in a timeout with a delay it seems to work:
$timeout(function () {
$scope.slides[6].active=true;
}, 100);
Upvotes: 2