简体   繁体   English

AngularJS ng-repeat with OwlCarousel

[英]AngularJS ng-repeat with OwlCarousel

What I'm trying to do is have angular build up the structure of my carousel using the ng-repeat directive, and then feed that to the owl carousel jquery plugin. 我正在尝试做的是使用ng-repeat指令将角度构建到我的轮播结构中,然后将其提供给owl carousel jquery插件。 Part of the trick is that this carousel is coming in with a view (ngView). 部分技巧是这个旋转木马进入视图(ngView)。

This, sadly, does not seem to be that simple. 遗憾的是,这似乎并不那么简单。

The options I have explored so far are: 我到目前为止探讨的选项是:

  1. $viewContentLoaded event. $viewContentLoaded事件。 This does not work, and is apparently frowned upon (since it amounts to DOM manipulation from the controller) 这不起作用,显然不赞成(因为它相当于控制器的DOM操作)
  2. Simply including some script at the bottom of the view page to initialize the carousel plugin. 只需在视图页面底部包含一些脚本即可初始化carousel插件。 This works for static content, but not for content added via ng-repeat 这适用于静态内容,但不适用于通过ng-repeat添加的内容
  3. Adding a custom directive. 添加自定义指令。 Ok, this works, but it seems to mean that I then have to build up the flippen entire carousel myself. 好吧,这样做有效,但这似乎意味着我必须自己建立整个旋转木马。 Nice use of jQuery.append() etc. Code for this follows beneath. 很好地使用jQuery.append()等代码。

Basically my question is this: is there some other/better way to do this (as opposed to endless looping and HTML string concatenations)? 基本上我的问题是:有没有其他/更好的方法来做到这一点(与无限循环和HTML字符串连接相反)?

Please note that the real carousel items I need to build up is a LOT more complicated that the sample below. 请注意,我需要建立的真正的旋转木马项目比下面的示例更复杂。

Ok, now some code: 好的,现在有些代码:

First, HTML snippet from the relevant view: 首先,来自相关视图的HTML片段:

<div class="owl-carousel owl-theme daCarousel" da-carousel="">
</div>

Next, the directive config: 接下来,指令配置:

app.directive('daCarousel',function () {
    var makeItLive = function (scope, element, attrs)
    {
        //TODO feed in real data here
        for (var i = 0; i < 10; i++) {                  
            $(element).append ('<div class="item">Item ' + i + '</div>');
        }

        $(element).owlCarousel({
            navigation : true, // Show next and prev buttons
            slideSpeed : 300,
            paginationSpeed : 400,
            singleItem:true                     

        });
};

EDIT 编辑

Ok, in the meanwhile I have discovered the $templateCache service. 好的,同时我发现了$templateCache服务。

In essence define a template in a script tag (mine is actually in the relevant view): 本质上是在脚本标签中定义一个模板(我的实际上是在相关的视图中):

<script type="text/ng-template" id="specialsTemplate.html">
//HTML with AngularJS bindings etc here
</script>

This you can then get at in your directive like so: 这样你就可以在你的指令中得到:

var tpl = $templateCache.get('specialsTemplate.html')   ;   
var compiled = $compile(tpl)(scope);
element.html (compiled);

For the last bit of magic, using oakfish's suggestion of $timeout : 对于魔法的最后一点,使用oakfish建议$timeout

$timeout (
            function () {
                $('#correctIdForYourCarouselElement').owlCarousel({

                    navigation : false, // Show next and prev buttons
                    slideSpeed : 300,
                    paginationSpeed : 400,
                    singleItem:true

                    // "singleItem:true" is a shortcut for:
                    // items : 1, 
                    // itemsDesktop : false,
                    // itemsDesktopSmall : false,
                    // itemsTablet: false,
                    // itemsMobile : false

                });
            },
            50
        );

Ok, to elaborate on my EDIT above, lets just give more rounded answer. 好的,详细说明我上面的编辑,让我们给出更全面的答案。

First, you need a controller to inject data into the scope of the directive (note that I'm NOT using an isolate scope thing here): 首先,您需要一个控制器将数据注入指令的范围(请注意,我在这里不使用隔离范围):

angular.module('ngApp')
.controller('MyCtrl', function ($scope) {
$scope.content = getDataSomeHow();
});

Next, define your template. 接下来,定义您的模板。 I found the relevant view was a good place in my case. 我发现相关的观点在我的案例中是个好地方。 Note, again, you might want to read up about isolate scopes. 另请注意,您可能希望了解有关隔离范围的信息。

<script type="text/ng-template" id="specialsTemplate.html">
                    <div class="item" ng-repeat="group in content" >
                        <div class="container">
                            <div class="row" ng-repeat="itemRow in group">                              
                                <div class="col-lg-2 outerItemContainer" ng-repeat="item in itemRow">
                                    <div class="itemContainer">

                                        <div class="someClasss">
                                            {{item.description}} 
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                </script>

Ok, next up, the actual directive. 好的,接下来是实际指令。 Note that the use of the pre and post did not help at all, I STILL had to use the $timeout service to get the carousel working. 请注意,使用prepost根本没有帮助,我仍然必须使用$timeout服务来使旋转木马工作。

angular.module('ngApp')
  .directive('specialsDirective', function ($compile,$templateCache,$timeout) {

    var buildIt = function (scope, element, attrs) {        

        var tpl = $templateCache.get('specialsTemplate.html')   ;   
        var compiled = $compile(tpl)(scope);
        element.html (compiled);
    };  

    var makeItScroll = function (scope, element,attrs) {    
            /* In THEORY, at this point it should be safe and fine
            * to call this jQM plugin. But it is not - does NOT work. Hence
            * the kludgy timeout crap here.
            */
            $timeout (
                function () {
                    $('#myCarousel').owlCarousel({

                        navigation : false, // Show next and prev buttons
                        slideSpeed : 300,
                        paginationSpeed : 400,
                        singleItem:true

                    });
                },
                50
            );

    };


    return {
      restrict: 'EA',
      replace:true,
      compile: function compile (tElement, tAttrs, transclude){
        return {
            pre: buildIt,
            post: makeItScroll
        }       
      }      
    };
  });

Ok, then the final bit, the actual directive use: 好的,那么最后一点,实际指令使用:

<div ng-controller="MyCtrl"  >
                    <div specials-directive="" id="myCarousel" class="owl-carousel owl-theme">                                      
                    </div>
                </div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM