Search code examples
javascriptangularjsangularjs-directiveangularjs-scopeflexslider

AngularJS only shows last Element in ng-repeat


I've got a strange behaviour using flexslider to render a bunch of galleries. As shown below I've got an array of several objects that conclude an array of images. When I "render" the galleries, all galleries appear but only the last one shows its images. On all galleries the indicator for the number of images in that particular, as well as the title and link, are correct, but the images are missing.

Do I do something(/a lot) wrong here? Here is my code:

$scope.galleries = [{title: 'gallery1', 'link': 'http://...', elements: 
                        ['img/img1.jpg','img/img2.jpg']},
                    {title: 'gallery2', 'link': 'http://...', elements: 
                        ['img/img3.jpg','img/img4.jpg']}];

I want to show each gallery with a directive and ng-repeat. The directive should show the title and render the gallery with flexslider(https://github.com/thenikso/angular-flexslider). Directive:

.directive('gallery', function() {
      return {
          restrict: 'A',
          templateUrl: 'views/gallery.html',
          scope: {
              gallery: '='
          },
          link: function(scope, element, attrs) {
              // first generate html, the

              // set content here
              scope.link = scope.gallery.link;
              scope.title = scope.gallery.title;
              scope.elements = angular.copy(scope.gallery.elements);
              scope.num = scope.gallery.elements.length;

          }
      };
  }

Here the template:

<a ng-href="{{link}}" target="_blank" ng-bind="title"></a>
<div class="gallery">
  <div class="flexslider">
    <div class="slides-control">
    <a href="" ng-click="prevSlideshow()" class="prev">
    <
      </a>
      <span class="current_pos">1</span>
      /
      <span ng-bind="num" class="total"></span>
        <a href="" ng-click="nextSlideshow()" class="next">
        >
      </a>
    </div>

        <ul ng-click="nextSlideshow()" class="slides" slideshow="false" control-nav="false" direction-nav="false" flex-slider slide="element in elements">
            <li><img ng-src="{{element}}" alt=""></li>
        </ul>
  </div>
  <a ng-href="{{link}}" target="_blank"><h4>more</h4></a>
<h5>---------------------------------------</h5>
</div>

And finally how i call it:

<ul class="publications" >
    <li ng-repeat="gallery in galleries">
        <div gallery="gallery"></div>
    </li>
</ul>

Solution

  • Well I've got some good news and some bad news...

    Good News You are doing nothing wrong in your code

    Bad News You are doing nothing wrong in your code

    Explanation The directive you're trying to use FlexSlider has some limitations as currently written. The reason you're only seeing one set of data rendered is because the association of the slide attribute and all other logic within the directive is written into the compile (see line 11 in flex-slider.js) function when anything related to the scope of the directive should be performed within the link function.

    Options

    1. Contact the developer of the directive and submit a bug report
    2. Resolve the issue yourself within the directive
    3. Write your own component

    Here is a plnkr I created This plnkr shows an ng-repeat that I added to illustrate that you're code should be working based upon how the directive was created.

    Note The developer likely never came across this scenario as the intention for creating it may have been to only have one instance at a time.