ui-carousel icon indicating copy to clipboard operation
ui-carousel copied to clipboard

Carousel slides do not update when the array changes

Open tarkant opened this issue 7 years ago • 3 comments

Hello there,

I've noticed that the carousel does not update the items displayed once we change the array of objects. Suppose we have a carousel loading items from var mySlides = [1, 2, 3, 4, 5, 6] and we decide to mutate the array to mySlides = [1, 2, 3, 4] or we add few elements, the slider won't get updated. This is pretty bad when you work with an API and fetch objects using a JSON or other.

tarkant avatar Apr 12 '17 17:04 tarkant

There are two problems;

  1. The watch function on the slides variable is using shallow comparison. So using an array as input, it will not notice changes because the reference to the array stays the same.
  2. In the watch function this.refreshCarousel(); is called. However this function does not copy the new input from the slides variable.

Solution I changed the watch function in the controller as following:

    /**
     * refresh model
     */
    $scope.$watch('slides', function () {
      _this.initOptions();
      _this.initRanges();
      _this.setProps();
      _this.setupInfinite();
      _this.refreshCarousel();
    }, true);

Bonus I also added a resize watcher, to make the carousel handle changes in display size.

    /**
     * update when resize
     */
    angular.element($window).on('resize', this.refreshCarousel);

    /**
     * cleanup when done
     */
    $scope.$on('$destroy', function () {
      angular.element($window).off('resize');
    });

mvanveen82 avatar Apr 25 '17 13:04 mvanveen82

@mvanveen82 Thanks for your quick. I also update on 162e07a and latest released

mihnsen avatar May 07 '17 23:05 mihnsen

/**
 * update when resize
 */
angular.element($window).on('resize', this.refreshCarousel);

/**
 * cleanup when done
 */
$scope.$on('$destroy', function () {
  angular.element($window).off('resize');
});

when you want to off an event listener you must declare the specific listener you want to remove. what this is doing angular.element($window).off('resize'); is remove all 'resize' listeners (including the one I need for something else :)).

It should be angular.element($window).off('resize', _this.refreshCarousel);

pazamit avatar Jul 24 '19 10:07 pazamit