Slick Carousel with Angular JS

2019-01-17 21:47发布

I am using Slick carousel in one of my AngularJS application. For that I have created directive as follows:

  myApp.directive('slickSlider',function(){
   return {
     restrict: 'A',
     link: function(scope,element,attrs) {
       $(element).slick(scope.$eval(attrs.slickSlider));
   }
  }
 }); 

Here is my code in view file:

  <div class="clearfix"  
  slick-slider="{dots: false, arrows: true, draggable: 
  false, slidesToShow:3, infinite:false}">
              <div class="my-slide">
                  <a><img ng-src="assets/img/img1.png"/></a>
              </div>
              <div class="my-slide">
                  <a><img ng-src="assets/img/img1.png"/></a>
              </div>
              <div class="my-slide">
                  <a><img ng-src="assets/img/img1.png"/></a>
              </div>
              <div class="my-slide">
                  <a><img ng-src="assets/img/img1.png"/></a>
              </div>
              <div class="my-slide">
                  <a><img ng-src="assets/img/img1.png"/></a>
              </div>
              <div class="my-slide">
                  <a><img ng-src="assets/img/img1.png"/></a>
              </div>
    </div>

In this case it is working fine and initializing properly.

But when I creates slides dynamically using ngRepeat, it is not initializing and shows slides one after the other.

Here is my code using ngRepeat

<div class="clearfix"  
  slick-slider="{dots: false, arrows: true, draggable: 
  false, slidesToShow:3, infinite:false}">
      <div class="my-slide" ng-repeat="slide in slides">
         <a><img ng-src="assets/img/{{slide.img}}"/></a>
       </div>
 </div>

Any suggestion, how can I resolve it?

2条回答
我只想做你的唯一
2楼-- · 2019-01-17 22:07

$timeout still didn't give the data enough time to initialise for my scenario so I modified the directive a bit more to watch for the data to have content (this could also have the effect of rebinding whenever the data changes, not just once the DOM initializes onLoad, if you change the use of isInitialized):

app.directive('slickSlider', function () {
    return {
        restrict: 'A',
        scope: {'data': '='},
        link: function (scope, element, attrs) {
            var isInitialized = false;
            scope.$watch('data', function(newVal, oldVal) {
                if (newVal.length > 0 && !isInitialized) {
                    $(element).slick(scope.$eval(attrs.slickSlider));
                    isInitialized = true;
                }
            });
        }
    }
});

This way angularJS watches for the data to be loaded and only hooks up the slick when data has length.

(btw $watch is necessary, instead of $observe, because "data" attribute doesn't use interpolation ( "{{...}}" ): Take a look at this great answer if you want to get the low-down on this.)

usage:

<div class="clearfix" data="slides" 
    slick-slider="{dots: false,
                   arrows: true,
                   draggable: false,
                   slidesToShow:3,
                   infinite:false}">
    <div class="my-slide" ng-repeat="slide in slides">
        <a><img ng-src="assets/img/{{slide.img}}"/></a>
    </div>
</div>

thanks to this so answer and this github that I got to from this so question

查看更多
贼婆χ
3楼-- · 2019-01-17 22:17

I suspect that the slick plugin may need the DOM to be fully rendered to work properly.

Try:

myApp.directive('slickSlider',function($timeout){
 return {
   restrict: 'A',
   link: function(scope,element,attrs) {
     $timeout(function() {
         $(element).slick(scope.$eval(attrs.slickSlider));
     });
   }
 }
}); 
查看更多
登录 后发表回答