Javascript 将 angularjs ng-repeat 应用到 owl-carousel
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27988502/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Applying angularjs ng-repeat to owl-carousel
提问by Fabii
<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>
View carousel here: Owl-carousel2
在此处查看轮播:Owl-carousel2
I'm running into an issue where whenever the ng-repeat directive is applied to carousel the items are stacked vertically instead of being layout horizontally.
我遇到了一个问题,每当 ng-repeat 指令应用于轮播时,项目都会垂直堆叠而不是水平布局。
If I leave out ng-repeat and use static items then it works as it should.
如果我省略 ng-repeat 并使用静态项目,那么它就可以正常工作。
Is there a directive I can write and apply to owl-carousel to maintain the layout?
是否有我可以编写并应用于 owl-carousel 以维护布局的指令?
Also what is about ng-repeat that is causing the carousel to break?
还有什么是导致转盘破裂的 ng-repeat ?
Is angular somehow stripping the owl-carousel classes applied to the carousel?
angular 是否以某种方式剥离了应用于轮播的 owl-carousel 类?
Note* If build the list manually then iterate through and append the elements using :
注意*如果手动构建列表,则使用以下方法迭代并附加元素:
var div = document.createElement('div');
var anchor = document.createElement('a');
var img = document.createElement('img');
.....
carousel.appendChild(div);
then call the owl.owlCarousel({..}) It works, not sure if this is the best work around because ng-repeat makes everything bit easier.
然后调用 owl.owlCarousel({..}) 它有效,不确定这是否是最好的解决方法,因为 ng-repeat 使一切变得更容易。
I discovered a hack , if I wrap the owl init in a timeout then ng-repat works.
我发现了一个 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>
回答by JKOlaf
Was able to modify a directive from DTingon another postto get it working with multiple carousels on the same page. Here is a working plnkr
能够在另一篇文章中修改来自DTing的指令,以使其与同一页面上的多个轮播一起使用。这是一个工作plnkr
-- Edit -- Have another plnkrto 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.
-- 编辑 -- 有另一个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());
}
}
};
}]);
Here is the HTML
这是 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>
回答by Fabii
I tried fiddling around with different directives but had no luck until I discovered this, it might a bit of a hack fix, but it works nonetheless.
我尝试摆弄不同的指令,但在我发现这一点之前一直没有运气,这可能是一个黑客修复,但它仍然有效。
Here is my div setup:
这是我的 div 设置:
<div ng-repeat="item in mediaitems">
<img ng-src="item.imageurl" />
</div>
$scope.mediaitems is generated using ajax call. I found that if I delayed the owl initialization until my list was populated then it would render it properly. Also if you decide you want update you list dynamically just call the setupcarousel function (look below) after the list has been populated and it will re-init the carousel.
$scope.mediaitems 是使用 ajax 调用生成的。我发现如果我延迟 owl 初始化直到我的列表被填充,那么它会正确地呈现它。此外,如果您决定要动态更新您的列表,只需在列表填充后调用 setupcarousel 函数(如下所示),它将重新初始化轮播。
Note that carousel init is in an external file within an anonymous function. That's just how I choosed to set it up, you can have yours in-line or however you please.
请注意,carousel init 位于匿名函数内的外部文件中。这就是我选择的设置方式,您可以将其串联或随心所欲。
In my controller I had something like this :
在我的控制器中,我有这样的事情:
$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{
....
}
})();
回答by Patrick Motard
The Angular UI Team has put together a set of bootstrap components implemented as angular directives. They are super sleek and fast to implement, and because they are directives, you don't run into issues with using jquery in an angular project. One of the directives is a carousel. You can find it hereand here. I messed around with carousels for a long time with angular. I got the owl to work after some annoying tinkering, but AngularUI's implementation is mucheasier.
Angular UI 团队已经将一组作为 angular 指令实现的引导组件放在一起。它们非常时尚且易于实现,并且因为它们是指令,所以在 angular 项目中使用 jquery 不会遇到问题。指令之一是轮播。你可以在这里和这里找到它。我用 angular 弄乱了旋转木马很长一段时间。经过一些烦人的修补后,我让猫头鹰开始工作,但 AngularUI 的实现要容易得多。
回答by Dash
This is the same answer as mentioned by JKOlaf. However I've added responsive behaviour to it which provides better UX. 2 major improvements: 1. Fully responsive code resulting better UX in different devices. 2. The "autoHeight" property is handled now resulting smaller thumbnail of the images.
这与 JKOlaf 提到的答案相同。但是,我已经为其添加了响应行为,从而提供了更好的 UX。2 项主要改进: 1. 完全响应式代码在不同设备上产生更好的用户体验。2. 现在处理“autoHeight”属性会产生较小的图像缩略图。
Code goes below:
代码如下:
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());
}
}
};
}]);
You can change the responsive item counts as per your requirement. Set it to a smaller value for larger thumbnail of images. Hope this will help somebody and Thanks to the original answer provider.
您可以根据需要更改响应项计数。对于较大的图像缩略图,将其设置为较小的值。希望这会帮助某人并感谢原始答案提供者。

