0

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;
             }
        }
    }

2 Answers 2

2

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);
Sign up to request clarification or add additional context in comments.

1 Comment

Yeah.... thought it would be something like that.... That's why I switched back to the original boostrap carousel. I don't want to be dependend on some timeout that that MIGHT be on time. If it is asynchronous (or at least uses timeouts) then I like to use a callbback, but there is none. So I can never be sure if this goes right. But thanks anyway ;-)
0

I just struggled with this problem. Here's my overly technical hack totally legit solution:

1. Create a new directive that overrides the 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.

2. Add the new directive to the carousel element

<carousel interval="myInterval" on-carousel-change>

3. Set the active slide on an event listener

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.