【问题标题】:Applying angularjs ng-repeat to owl-carousel将angularjs ng-repeat应用于owl-carousel
【发布时间】:2015-01-16 16:33:43
【问题描述】:
<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 并使用静态项目,那么它应该可以正常工作。

是否有我可以编写并应用于 owl-carousel 以维护布局的指令?

还有 ng-repeat 导致轮播中断的原因是什么?

Angular 是否以某种方式剥离了应用于轮播的 owl-carousel 类?

注意* 如果手动构建列表,则使用 :

遍历并附加元素
var div = document.createElement('div');
var anchor = document.createElement('a');
var img = document.createElement('img');            
.....       
carousel.appendChild(div);

然后调用 owl.owlCarousel({..}) 它可以工作,不确定这是否是最好的解决方法,因为 ng-repeat 让一切变得更容易。

我发现了一个 hack,如果我将 owl init 包裹在超时中,那么 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>

【问题讨论】:

  • 你用什么代码来加载猫头鹰轮播?这几乎可以肯定是一个加载顺序问题。即 ng-repeat 在 owl carousel 从中构建 carousel 之前没有操纵 DOM。
  • @rwacarter 查看我上面添加的内容
  • @rwcarter 如果这确实是问题,我该如何解决?
  • 我是否应该构建我的列表,然后在填充列表后调用 owl-carousel build?
  • setTimeout(function(){ ...call owl init now },1000);加载列表后的技巧

标签: javascript angularjs angularjs-directive owl-carousel


【解决方案1】:

能够在另一个post 上修改来自DTing 的指令,使其与同一页面上的多个轮播一起工作。这是一个有效的plnkr

-- 编辑-- 请另一个plnkr 举例说明如何添加项目。执行 reinit() 不起作用,因为任何时候 owl carousel 被破坏,它都会丢失数据元素并且永远无法再次初始化。

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="angular.js@1.3.x" src="https://code.angularjs.org/1.3.15/angular.js" data-semver="1.3.15"></script>
    <script data-require="jquery@2.1.3" 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>

【讨论】:

  • 感谢您的回答。这很棒。它等待最后一个项目循环然后初始化轮播的事实,在处理异步事件/加载外部内容时有很大的不同。
  • 使用这个没有显示猫头鹰点
  • 如果我的数组中的每个项目都是一个单独的 GET 请求并且在每个响应之后 if(scope.$last) 是真的,我该怎么办?所有项目都在轮播之外,如何解决?
  • 我想重新启动轮播。我在 scope.initcarousel 函数中应用为 "scope.$watchCollection('item', function(newValue, oldValue) { if (newValue){ element.data('owlCarousel').reinit({items : 5, pagination: false , rewindNav : false,responsiveClass:true, itemsCustom:[[768,5]]}); } });"但它在每次重新初始化时都会给出空项目。
  • 我在 owl.reinit() 方面没有取得任何成功,但我在添加单个项目方面确实取得了成功。我在 ::items1 和 ::items2 上让观察者关闭,只需将一个新数字推送到数组并通过函数添加 html。更新的 plnkr 可以在这里找到:plnkr.co/edit/qAnXhA7yVyZDQUq6sXGY?p=preview
【解决方案2】:

我尝试摆弄不同的指令,但在我发现这一点之前一直没有运气,这可能是一个黑客修复,但它仍然有效。

这是我的 div 设置:

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

$scope.mediaitems 是使用 ajax 调用生成的。我发现如果我延迟 owl 初始化,直到我的列表被填充,那么它会正确呈现它。此外,如果您决定要动态更新列表,只需在填充列表后调用 setupcarousel 函数(如下所示),它将重新初始化轮播。

请注意,carousel init 位于匿名函数内的外部文件中。这就是我选择设置它的方式,你可以让你的在线或任何你喜欢的。

在我的控制器中,我有这样的东西:

$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{
      ....
    }

})();

【讨论】:

  • 我有一个非常相似的问题,你的方法对我来说很有意义。然而,这一行“owl.data('owlCarousel').destroy();”不起作用 - 它告诉我它不能删除“未定义”的属性。帮忙?
  • 没关系,找到问题了!无论出于何种原因,“if(typeof owl.data('owlCarousel') != 'undefined')” 行并没有为我捕获未定义的对象,所以我只是将其分解为“var owlData = owl.data(' owlCarousel')" 在 if 之前,然后执行 "if(owlData === undefined)",它就像一个魅力。谢谢!
【解决方案3】:

Angular UI 团队将一组引导组件组合在一起,实现为 Angular 指令。它们非常时尚且易于实现,并且因为它们是指令,所以在 Angular 项目中使用 jquery 不会遇到问题。其中一个指令是轮播。你可以找到它herehere。我在旋转木马上玩了很长时间,有角度。经过一些烦人的修补后,我让猫头鹰开始工作,但 AngularUI 的实现要容易得多

【讨论】:

    【解决方案4】:

    这与 JKOlaf 提到的答案相同。但是,我已经为其添加了响应行为,从而提供了更好的用户体验。 2 大改进: 1. 完全响应的代码在不同的设备上产生更好的用户体验。 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());
                }
            }
        };
    }]);

    您可以根据需要更改响应项目数。将其设置为较小的值以获得较大的图像缩略图。 希望这会对某人有所帮助,并感谢原始答案提供者。

    【讨论】:

    • 可以用嵌套的 ng-if 语句完成这样的事情吗,我有一组要嵌入的视频和一组图片。当您在评估 scope.$last 时到达 owlCarouselItem 时,这会变得很棘手
    猜你喜欢
    • 2014-09-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多