vasyabigi / angular-slick

Angular directive for slick-carousel
http://vasyabigi.github.io/angular-slick/
MIT License
500 stars 237 forks source link

not working with dynamic data #105

Open esperancaJS opened 9 years ago

esperancaJS commented 9 years ago

for data the changes multiple times this still doesn't seem to work :(

nicolas-besnard commented 9 years ago

Same issue here ...

esperancaJS commented 9 years ago

I ended up by just restarting slick everytime data changes as a temporary fix

nicolas-besnard commented 9 years ago

How did you do that ? Le sam. 20 juin 2015 à 05:46, PedroEsperanca notifications@github.com a écrit :

I ended up by just restarting slick everytime data changes as a temporary fix

— Reply to this email directly or view it on GitHub https://github.com/vasyabigi/angular-slick/issues/105#issuecomment-113704124 .

esperancaJS commented 9 years ago

I even stopped using angular slick, I found it easier to just create my own directive..

$('#your-slick').slick('unslick'); //terminates (only run if slick is initialized) //update view now $('#your-slick').slick(); //start

nicolas-besnard commented 9 years ago

That's what I've done so far.

On Sat, Jun 20, 2015 at 3:12 PM PedroEsperanca notifications@github.com wrote:

I even stopped using angular slick, I found it easier to just create my own directive..

$('#your-slick').slick('unslick'); //terminates (only run if slick is initialized) //update view now $('#your-slick').slick(); //start

— Reply to this email directly or view it on GitHub https://github.com/vasyabigi/angular-slick/issues/105#issuecomment-113766522 .

mhulse commented 9 years ago

@PedroEsperanca Not sure if this is possible, but could you provide your complete slick directive?

esperancaJS commented 9 years ago

Hope this helps you @mhulse, sorry for using jquery selectors as it's a bad practice, but take notes from everything else ;)

The JS

Note that I'm using $rootScope.$on to detect changes in the image array since a watcher is too slow if the image is base64

//item-pop-up-slick
marketApp.directive('itemPopUpSlick', [ 
    '$timeout', '$rootScope',
    function($timeout, $rootScope){
    return {
        link: function($scope, $element, attrs){

            $scope.showslick = false;
            $scope.imgs = angular.extend([], $scope.item.global.galery);

            function startSlick(toshow){
                $timeout((function() {

                    $('#slider-nav').on('init', function(event){
                        $scope.showslick = true;
                    });
                    $('#slider-for').slick({
                        slidesToShow: 1,
                        slidesToScroll: 1,
                        arrows: false,
                        fade: true,
                        asNavFor: '#slider-nav',
                    });

                    $('#slider-nav').slick({
                        slidesToShow: 4,
                        slidesToScroll: 1,
                        asNavFor: '#slider-for',
                        focusOnSelect: true,
                        arrows: true,
                        infinite: false,
                    });

                    $scope.currentSlide = 0;
                    $('#slider-for').on('beforeChange', function(event, slick, currentSlide, nextSlide){
                        $scope.currentSlide = nextSlide;
                        $scope.$apply();
                    });

                }), 1);
            }
            $scope.showslick = true;
            startSlick()

            $rootScope.$on("itemimgschanged", function(val1, val2) {
                if($scope.showslick){
                    $('#slider-for').slick('unslick');
                    $('#slider-nav').slick('unslick');
                }
                $scope.showslick = false;
                $timeout((function() {
                    $scope.imgs = angular.extend([], $scope.gitem.global.galery);
                    startSlick()
                }), 1);
            });

        }
    };
}]);

the HTML

<div 
    item-pop-up-slick 
    class="item-pop-up-slick" 
    ng-class="{
        'opacity-0' : !showslick
    }"
>
    <div
        id="slider-for"
        style="margin-bottom: 0"
    >
        <div 
            ng-repeat="img in imgs"
            img-preview="img" img-model="imgPrev" img-size="w_1000"
            ng-show="imgPrev"
            id="{{$index}}"
        >
            <div
                class="img-container"
                ng-style="{
                    'background-image':'url('+imgPrev+')'
                }"
            >
                <img ng-src="{{imgPrev}}" />
            </div>
        </div>
    </div>
    <div>
        <div
            id="slider-nav"
        >
            <div 
                ng-repeat="img in imgs"
                img-preview="img" img-model="imgPrev" img-size="w_1000"
                ng-show="imgPrev"
                id="{{$index}}"
                ng-class="{
                    'selected': currentSlide === $index
                }"
            >
                <div
                    class="img-container"
                    ng-style="{'background-image':'url('+imgPrev+')'}" 
                >
                    <img ng-src="{{imgPrev}}" />
                </div>
            </div>
        </div>
    </div>
</div>
mhulse commented 9 years ago

Thanks for sharing @PedroEsperanca, I greatly appreciate it!!!! :)

I've been having a heck of a time finding a carousel that works for html content and dynamic data.

Trying your example now. Thanks so much for example! I'm new to angular, so it really helps to see how you've done it. :+1: :octocat:

mhulse commented 9 years ago

@PedroEsperanca again, thanks so much for the example code. It's really helped me out. :+1:

I also found this modification to be helpful: https://github.com/vasyabigi/angular-slick/issues/81#issuecomment-98307691

i.e. using controller to show/hide upon beforeSlick and afterSlick callbacks.

sannac commented 9 years ago

This worked for me: In your controller, add a function where you compile the cloned slides with the scope (don't forget to add $compile to your dependencies):

$scope.initSlick = function() { $compile(angular.element(".slick-cloned"))($scope); };

Then in you HTML, just call the function at the onInit event:

slick.bp-tc( arrows="false", infinite="true", center-mode="true", focus-on-select="true", on-init= "initSlick()", ...

MantasR commented 9 years ago

Make sure that you dynamic data variable is initialized on load: in your controller:

$scope.myData = null;

$scope.loadData = function()
{
    $scope.myData = ...;
}

in html:

<slick lazy-load="ondemand" init-onload='true' data="myData" ... >...</slick>

It worked for me.

henriquecholo commented 9 years ago

None of those worked for me.

lorentzyip commented 9 years ago

Thanks MantasR! Your solution works for my case. I did try sometime like $scope.myData = [] and it didn't work so initialising data to null is crucial.

anmolgupta commented 8 years ago

non of the solution worked for me

gaojianzhuang commented 8 years ago

@MantasR When the "myData" is a collection, and we use "ng-repeat" as the slick items. And the "myData" has some filters, this way will failed when do the filter operation.

<slick lazy-load="ondemand" init-onload='true' data="myData"> <div ng-repeat="item in myData | filter: name"></div> </slick>

Do you encounter this senario?

MichaelJGW commented 8 years ago

One method is to focus on the initialization of the directive. When you use ng-if it removes the directive and place it back with place the directive back in the DOM and reinitializing the directive without reinitializing slick itself.

Controller

  function updateSlickData(){
    $scope.slickData = [];
    $timeout(function(){
      dataFactory.data(function(res) {
        $scope.slickData = res;
      });
    },0);
  }

HTML

<slick id="slickID" data="slickdata" ng-if="slickData.length">
    <div ng-repeat="item in slickData">{{item.text}}</div>
</slick>
KyawNaingTun commented 8 years ago

Thank you sir 👍 @MantasR

sepalacio commented 7 years ago

Thanks MantasR! Your solution should be the acepted answer.