1

This is most likely going to be another Angular scope question. I looked hard for a solution on SO, however, nothing I found would solve my problem.

I am using Angular.js together with Swiper.js. Inside one slide of an outer vertical swiper, I have an inner horizontal swiper showing only if (ng-if) the user selects an audio (not a video); then the user may swipe between a number of images (ng-repeat). These images have captions which I want to clickable (ng-click) so they can be hidden/shown (ng-show).

Everything is working except for the hiding and showing after a click. I tried distributing the ng-directives among several code levels (divs), and I tried doing with or without a call to my controller functions.

Here is my code:

<div ng-if="selectedMedium().class === 'Audio'" class="swiper-container swiper-container-images">
    <div class="swiper-wrapper">
        <div ng-repeat="image in selectedImages track by $index" end-repeat class="swiper-slide images">
            <img class="image" ng-src="{{ image }}">
            <a class="caption" href="#" ng-init="show = true" ng-show="show" ng-click="show = !show">{{ selectedCaptions[$index] }}</a>
        </div>
    </div>
    <div class="swiper-pagination"></div>
</div>

For the sake of completeness, I include the $scope.selectedMedium function (within the controller) and the end-repeat directive (which marries Angular and Swiper, outside the controller):

$scope.selectedMedium = function() {
    for (var i = 0; i < $scope.media.length; i++) {
        if ($scope.media[i].person === $scope.selectedPerson.person && $scope.media[i].topic === $scope.selectedTopic.topic) {
            $scope.selectedImages = ("imageFiles" in $scope.media[i]) ? $scope.media[i].imageFiles : null;
            $scope.selectedCaptions = ("imageSubtitles" in $scope.media[i]) ? $scope.media[i].imageSubtitles : null;
            return $scope.media[i];
        }
    }
    return "Error";
};

myApp.directive('endRepeat', ['$timeout', function($timeout) {
    return {
        restrict: 'A',
        link: function(scope, element, attr) {
            if (scope.$last === true) {
                $timeout(function() {
                    scope.$emit('ngRepeatFinished');
                });
            }
        }
    }
}]);

In the above code I tried to do without any reference to the functions in my controller, but in other versions I tried to reconnect from the (multiple, I guess) childscope(s) to $scope by putting something like:

<a class="caption" href="#" ng-show="$parent.isCaptionShowing[$index]" ng-click="$parent.isCaptionShowing[$index] = !$parent.isCaptionShowing[$index]">{{ selectedCaptions[$index] }}</a>

I even tried $parent.$parent.isCaptionShowing[$index]. For this approach I added the following line to my $scope.selectedMedium function:

$scope.isCaptionShowing = ($scope.selectedCaptions !== null) ? new Array($scope.selectedCaptions.length).fill(true) : null;

Neither approach (all inside the HTML code vs. a call to the controller functions) worked. I seems that the ng-click function does not worked as intended. Any ideas what might be the problem?

kalabalik
  • 3,792
  • 2
  • 21
  • 50
  • What happens if you try `ng-show` rather than `ng-if`? Also - try creating plunkr / jsfiddle / codepen / jsbin type of demo to make experimenting easier. – Mars Robertson May 03 '17 at 14:24
  • place `show` property on `image` level like `image.show` & don't use `ng-init` each time it will reset `show` property to true. Rather set it to true, when you creating `selectedImage` array from controller itself.. – Pankaj Parkar May 03 '17 at 14:27
  • ng-show instead of ng-if does not change anything (nor does anything change if I replace ng-show with ng-if in the a-tag line. The point about ng-init is a valid one, but also does not solve the main problem. I changed my data structure and now I have objects with properties `image`, `caption` and `show`. Feels much better, but still does not solve the problem. So I created a [codepen]: https://codepen.io/anon/pen/zwdpgg with much destilled code and ... nothing that works on my machine works in codepen, but that which does not work on my machine (the hiding) does work there. I am clueless why. – kalabalik May 04 '17 at 00:24
  • Okay, got it. A very wierd problem. "All" I had to do, is disable one line of code in the CSS shipped with Swiper. The pagination dots which I moved to the top of the page must have somehow blocked access to the captions (although I increased the z-index of the latter to 1000). Sorry to have bothered you and sorry for the waste of my own time. – kalabalik May 04 '17 at 09:14

0 Answers0