Search code examples
javascriptangularjsangularjs-ng-repeatangularjs-ng-clickng-show

Angular: Why is my div not showing/hiding with ng-show/ng-hide?


I'm trying to make a super simple lightbox for some images. Basically I have a div with a set of images showing up using ng-repeat, and I want to have a lightbox div show up when one of the images is clicked. I can't figure out why my lightbox div won't appear. Here is my code:

angular.module('myApp')
.controller('PhotosCtrl', ['$scope', function PhotosCtrl($scope){
	$scope.photos = [
		{
			src: '/images/img1.png',
			caption: ' '
		},
		{
			src: '/images/img2.png',
			caption: ' '
		}
	];
	$scope.larges = [
		{
			src: '/images/img1-lg.png',
			caption: ' '
		},
		{
			src: '/images/img2-lg.png',
			caption: ' '
		}
	];
}]);
.photowrap{
	max-width: 85%;
	margin: 0 auto;
	padding: 12px 0;
	display: flex;
	flex-flow: row wrap;
	justify-content: center;
	background-color: #fff;
}
.photos{
	margin: 0;
}
.photo{
	max-height: 250px;
	border: 2px solid #EBEBEB;
	border-radius: 5px;
}
p.caption{
	display: none;
}

.lightbox{
	max-width: 85%;
	margin: 0 auto;
	background-color: rgba(255,255,255,0.6);
	position: absolute;
}
.lbphoto{
	max-width: 100%;
	max-height: 100%;
	display: block;
	margin: 0 auto;
}
<div ng-controller="PhotosCtrl" class="content">
  <div class="photowrap">
    <a href="" ng-repeat="photo in photos" ng-click="showme=true" class="photos">
      <img ng-src="{{photo.src}}" class="photo img-responsive"/>
    </a>
    <div ng-show="showme" class="lightbox">
      <a href="" ng-repeat="large in larges" class="photos">
        <a ng-click="showme=false" class="close">x</a>
        <img ng-src="{{large.src}}" class="lbphoto img-responsive"/>
      </a>
    </div>
  </div>
</div>

Can anyone help me figure out what I'm doing wrong?

Thanks!


Solution

  • Because on each iteration ng-repeat does create a prototypically inherited child scope. So while creating child scope, object value gets passed with there reference inside child scope but the primitive type values are just passes there initial value. When primitive types value(here showme) gets modified inside the child scope, that variable creates a new copy inside child scope(when ng-click of inner ng-repeat chnages the value of showme it will be new variable copy of showme). You could solve such kind of issue by taking help of reference type objects.

    Here what you can do is, make showme property as a part of outer ng-repeat which photo element. By which you will ensure that you are relying on the reference object which is photo.

    Also you have to move ng-repeat to one step above, so that photo object will get avaialble inside inner ng-repeat, currently both the ng-repeat on same level.

    Markup

    <div ng-controller="PhotosCtrl" class="content">
      <div class="photowrap" ng-repeat="photo in photos">
        <a href="" ng-click="photo.showme=true" class="photos">
          <img ng-src="{{photo.src}}" class="photo img-responsive"/>
        </a>
        <div ng-show="photo.showme" class="lightbox">
          <a href="" ng-repeat="large in larges" class="photos">
            <a ng-click="photo.showme=false" class="close">x</a>
            <img ng-src="{{large.src}}" class="lbphoto img-responsive"/>
          </a>
        </div>
      </div>
    </div>