Question

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>
Was it helpful?

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.

OTHER TIPS

Thank you all for bringing up this problem and analyze it! It was indeed an angular-flexslider's directive issue. It has been addressed in http://github.com/thenikso/angular-flexslider/issues/20

General information for users who begin with AngularJs :

Some times you use dropdown with ng-repeat

<a href="#" class="dropdown-toggle" data-toggle="dropdown">Language</a>
<ul class="dropdown-menu" ng-repeat="language in languages">
    <li>
        <a href="#">{{ language.name | translate }}</a>
    </li>
</ul>

Don't forget that ng-repeat will repeat the ul too. The output is :

<li class="dropdown">
    <a href="#" class="dropdown-toggle" data-toggle="dropdown">Language</a>
    <ul class="dropdown-menu ng-scope" role="menu" ng-repeat="language in languages">
        <li><a href="#" ng-click="changeLanguage(language.abv)" class="ng-binding">French</a></li>
    </ul>
    <ul class="dropdown-menu ng-scope" role="menu" ng-repeat="language in languages">
        <li><a href="#" ng-click="changeLanguage(language.abv)" class="ng-binding">English</a></li>
    </ul>
</li>

We can see two ul with a dropdown, this is bad, this is why you can see only last element of the arrays. This is the correct way :

<a href="#" class="dropdown-toggle" data-toggle="dropdown">Language</a>
<ul class="dropdown-menu">
    <li ng-repeat="language in languages">
        <a href="#">{{ language.name | translate }}</a>
    </li>
</ul>

Hope it help !

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top