Problem: I want to create a modal lightbox using the Angular UI Bootstrap modal
Details: I have built a photo grid using ng-repeat. Each repeated photo opens the modal using the open() method. I'm struggling with how to pass the scope of the clicked item to the modal so I can grab the image url to display. I've implemented the scope parameter on the modal, which gives me access to the parent; however the parent is the parent scope of the clicked item and contains the whole array of all images in the grid. I need to figure out how to tell (programmatically) which index has been clicked, or send just the child scope to the modal. I'm a newbie... if I'm missing something or there's a better way to approach this, any help is welcome.
My HTML:
<section ng-controller="ModalDemoCtrl">
<div ng-repeat="photo in photos.data">
<img src="{{photo.source}}" class="thumbnail img-responsive" ng-click="open()">
</div>
</section>
Instance and controller:
app.controller('ModalDemoCtrl', function ($scope, $modal, $log) {
$scope.items = ['item1', 'item2', 'item3'];
$scope.open = function (scope) {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
scope: $scope,
controller: ModalInstanceCtrl,
resolve: {
items: function () {
return $scope.items;
},
// this returns as undefined
photo: function(){
return $scope.photo;
}
}
});
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
});
var ModalInstanceCtrl = function ($scope, $modalInstance, items, photo) {
$scope.items = items;
$scope.photo = photo;
$scope.selected = {
item: $scope.items[0]
};
$scope.ok = function () {
$modalInstance.close($scope.selected.item);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
console.log($scope);
};
This is basically how scope looks. The item index I need is buried deep and I need to know (programmatically) which one was clicked. I need the source off Index[0]
$scope
--$parent
---$parent
----$photos
-----$$v
------data
-------0
--------Source
-------1
-------2
-------3
-------4
-------5
-------6
-------7
-------8
You could just do something like this.
HTML
<img src="{{photo.source}}" class="thumbnail img-responsive" ng-click="open(photo)">
Javascript
$scope.open = function (photo) {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
scope: $scope,
controller: ModalInstanceCtrl,
resolve: {
items: function () {
return $scope.items;
},
photo: function(){
return photo;
}
}
});
I tried to post this as a comment but apparently it's too long. So, I will post it as an answer even though the correct answers have been given.
If your definition was
$scope.open = function (xyz) {...
then your resolve would be
...photo: function(){ return xyz;}
You just got confused because you had used string name 'photo' as your function parameter. It has nothing to do with the scope. Also in your resolve definition, you could have called it anything instead of photo
...abc: function() {return xyz}
and then use abc in your
ModelInstanceCtrl(... , abc)
Again, there is no link to scope here. You are just passing along a value from
open(photo) to function (xyz) to ModalInstanceCtrl (... , abc)
Within the controller you can set it to anything you would like
$scope.xxx = abc;
photo actually does not exist in the main scope since ng-repeat creates a local scope within the loop. photo is only visible within the loop and that's why you have to pass along to the controller through the function open() parameter. I am new to Angular and keeping track of scope lives has been challenging. Experts out there, please correct me if I am wrong.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With