mihnsen / ui-carousel

A simple, lightweight module for carousel in your AngularJS app, Inspired from slick carousel.
http://mihnsen.github.io/ui-carousel/
MIT License
77 stars 67 forks source link

Carousel slides do not update when the array changes #10

Open tarkant opened 7 years ago

tarkant commented 7 years ago

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.

mvanveen82 commented 7 years ago

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');
    });
mihnsen commented 7 years ago

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

pazamit commented 4 years ago
/**
 * 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);