web-dev-qa-db-ja.com

angularjs ng-repeatをフクロウカルーセルに適用する

<div class="owl-carousel">
    <div ng-repeat="items in itemlist"> 
        <a href="series.html"><img ng-src="{{items.imageUrl}}" /></a>
    </div>
    <div> 
      <a href="series.html"><img src="http://placehold.it/350x150" /></a>
    </div>
 </div>

ここでカルーセルを表示: Owl-carousel2

カルーセルにng-repeatディレクティブが適用されるたびに、アイテムが水平にレイアウトされるのではなく垂直にスタックされるという問題に直面しています。

Ng-repeatを省略して静的なアイテムを使用すると、正常に機能します。

レイアウトを維持するために、フクロウカルーセルに記述して適用できるディレクティブはありますか?

また、カルーセルが破損しているng-repeatについてはどうですか?

angular何らかの形でカルーセルに適用されたフクロウカルーセルクラスを削除しますか?

注*リストを手動で作成する場合は、次を使用して要素を繰り返し処理して追加します。

var div = document.createElement('div');
var anchor = document.createElement('a');
var img = document.createElement('img');            
.....       
carousel.appendChild(div);

次にowl.owlCarousel({..})を呼び出します。ng-repeatによりすべてが少し簡単になるため、これが最善の回避策かどうかはわかりません。

ハックを発見しました。フクロウの初期化をタイムアウトでラップすると、ng-repatが動作します。

setTimeout(function(){
      ...call owl init now  
},1000);

<link rel="stylesheet" href="css/owl.carousel.css"/>
<link rel="stylesheet" href="css/owl.theme.default.min.css"/>

.....
    <script src="/js/lib/owl.carousel.min.js"></script> 
        <script>
             $(document).ready(function() {
               var owl = $('.owl-carousel');
               owl.owlCarousel({
                 .....
               });
               owl.on('mousewheel', '.owl-stage', function(e) {
                 if (e.deltaY > 0) {
                   owl.trigger('next.owl');
                 } else {
                   owl.trigger('prev.owl');
                 }
                 e.preventDefault();
               });
             })

        </script>
13
Fabii

DTing 別の post のディレクティブを変更して、同じページ上の複数のカルーセルで動作するようにできました。動作する plnkr

-編集-別の plnkr を使用して、アイテムの追加方法の例を示します。 reinit()を実行しても、フクロウのカルーセルが破棄されるたびに動作しませんでした。データ要素を失い、再度初期化することはできません。

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.items1 = [1,2,3,4,5];
  $scope.items2 = [1,2,3,4,5,6,7,8,9,10];
}).directive("owlCarousel", function() {
    return {
        restrict: 'E',
        transclude: false,
        link: function (scope) {
            scope.initCarousel = function(element) {
              // provide any default options you want
                var defaultOptions = {
                };
                var customOptions = scope.$eval($(element).attr('data-options'));
                // combine the two options objects
                for(var key in customOptions) {
                    defaultOptions[key] = customOptions[key];
                }
                // init carousel
                $(element).owlCarousel(defaultOptions);
            };
        }
    };
})
.directive('owlCarouselItem', [function() {
    return {
        restrict: 'A',
        transclude: false,
        link: function(scope, element) {
          // wait for the last item in the ng-repeat then call init
            if(scope.$last) {
                scope.initCarousel(element.parent());
            }
        }
    };
}]);

ここにHTMLがあります

<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/owl-carousel/1.3.3/owl.carousel.min.css" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/owl-carousel/1.3.3/owl.theme.min.css" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/owl-carousel/1.3.3/owl.transitions.min.css" />
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/owl-carousel/1.3.3/owl.carousel.min.js" />
    <script data-require="[email protected]" src="https://code.angularjs.org/1.3.15/angular.js" data-semver="1.3.15"></script>
    <script data-require="[email protected]" data-semver="2.1.3" src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/owl-carousel/1.3.3/owl.carousel.min.js"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <data-owl-carousel class="owl-carousel" data-options="{navigation: true, pagination: false, rewindNav : false}">
      <div owl-carousel-item="" ng-repeat="item in ::items1" class="item">
        <p>{{::item}}</p>
      </div>
    </data-owl-carousel>
    <data-owl-carousel class="owl-carousel" data-options="{navigation: false, pagination: true, rewindNav : false}">
      <div owl-carousel-item="" ng-repeat="item in ::items2" class="item">
        <p>{{::item}}</p>
      </div>
    </data-owl-carousel>
  </body>

</html>
25
JKOlaf

私はさまざまなディレクティブをいじってみましたが、これを発見するまで運がありませんでした。それは少しハックの修正かもしれませんが、それでも動作します。

私のdiv設定は次のとおりです。

<div ng-repeat="item in mediaitems">
  <img ng-src="item.imageurl" />
</div>

$ scope.mediaitemsは、ajax呼び出しを使用して生成されます。リストにデータが入力されるまでフクロウの初期化を遅らせた場合、適切にレンダリングされることがわかりました。また、更新したい場合は、リストにデータが追加された後にsetupcarousel関数(下記を参照)を動的に呼び出すだけで、カルーセルが再初期化されます。

カルーセルの初期化は、匿名関数内の外部ファイルにあることに注意してください。それは私がそれをセットアップすることを選んだ方法です。

私のコントローラーには次のようなものがありました。

$scope.populate = function(){
     $timeout(function(){   
      $scope.mediaitems  = returnedlist;   //list of items retrun from server
       utils.setupcarousel();              //call owl initialization
     });
};

var utils = (function(){
    var setupcarousel = function(){
        console.log('setting up carousel..');
         var owl = $('.owl-carousel');
         if(typeof owl.data('owlCarousel') != 'undefined'){
             owl.data('owlCarousel').destroy();
             owl.removeClass('owl-carousel');
         }

        owl.owlCarousel({
            loop: false,
            nav: true,
            margin: 10,
            responsive: {
              0: {items: 3 },
              600: {items: 5},
              960: { items: 8},
              1200:{items: 10},
              1600:{items: 12}
            }
          });
    };

    return{
      ....
    }

})();
5
Fabii

Angular UIチームは、bootstrapコンポーネントをangularディレクティブとして実装しました。これらは非常に滑らかで高速です。これらはディレクティブであるため、angularプロジェクトでjqueryを使用する際に問題が発生することはありません。ディレクティブの1つはカルーセルです。見つけることができます here and here 。私は長い間、カルーセルをいじり回していました。 much簡単です。

1
Patrick Motard

これは、JKOlafが述べたのと同じ答えです。しかし、より良いUXを提供するレスポンシブ動作を追加しました。 2つの主要な改善:1.完全にレスポンシブなコードにより、さまざまなデバイスで優れたUXが得られます。 2.「autoHeight」プロパティが処理され、画像のサムネイルが小さくなりました。

コードは以下のとおりです。

        
Was able to modify a directive from DTing on another post to get it working with multiple carousels on the same page. Here is a working plnkr

-- Edit -- Have another plnkr to give an example on how to add an item. Doing a reinit() did not work cause any time the owl carousel is destroyed it loses the data- elements and can never initialize again.

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.items1 = [1,2,3,4,5];
  $scope.items2 = [1,2,3,4,5,6,7,8,9,10];
}).directive("owlCarousel", function() {
    return {
        restrict: 'E',
        transclude: false,
        link: function (scope) {
            scope.initCarousel = function(element) {
              // provide any default options you want
                var defaultOptions = {
                };
                var customOptions = scope.$eval($(element).attr('data-options'));
                // combine the two options objects
                for(var key in customOptions) {
                    defaultOptions[key] = customOptions[key];
                }
                defaultOptions['responsive'] = {
                    0: {
                        items: 1
                    },
                    600: {
                        items: 3
                    },
                    1000: {
                        items: 6
                    }
                };
                // init carousel
                $(element).owlCarousel(defaultOptions);
            };
        }
    };
})
.directive('owlCarouselItem', [function() {
    return {
        restrict: 'A',
        transclude: false,
        link: function(scope, element) {
          // wait for the last item in the ng-repeat then call init
            if(scope.$last) {
                scope.initCarousel(element.parent());
            }
        }
    };
}]);

要件に応じてレスポンシブアイテムの数を変更できます。画像のサムネイルを大きくするには、小さい値に設定します。これが誰かを助け、元の回答プロバイダーに感謝することを願っています。

0
Dash