web-dev-qa-db-ja.com

Angular JSを使用した滑らかなカルーセル

Slick カルーセルを AngularJS アプリケーションの1つで使用しています。そのために、次のようにディレクティブを作成しました。

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

ビューファイル内の私のコードは次のとおりです。

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

この場合、問題なく機能し、適切に初期化されています。

しかし、 ngRepeat を使用してスライドを動的に作成すると、初期化されず、スライドが次々に表示されます。

これが 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>

何か提案があれば、どうすれば解決できますか?

15
Kalpesh Patel

Slickプラグインが適切に機能するには、DOMを完全にレンダリングする必要があるのではないかと思います。

試してください:

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

$ timeoutはまだ私のシナリオのために初期化するのに十分な時間をデータに与えなかったので、データがコンテンツを持つのを監視するためにディレクティブをもう少し変更しました(これはまた、データが変更されるたびにではなく、データが変更されるたびに再バインドする効果を持つ可能性がありますisInitializedの使用を変更した場合、DOMはonLoadを初期化します。

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

このように、angularJSはデータがロードされるのを監視し、データに長さがある場合にのみスリックをフックします。

(btw $ watchの代わりに$ watchが必要です。 "data"属性は補間( "{{...}}"を使用しないためです): this great answer を見てくださいこれについてローダウンを取得したいです。)

使用法:

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

this so answerthis github に感謝します this so質問

11
lukkea