问题
I am building an application with angular where I have a list of items (using ng-repeat), and by clicking on each item I can open a modal in order to see a more detailed description.
Right now in order to switch to another modal I have to close the previous one, go to the list, and click to open another modal. I would like to go directly to the previous/next modal when clicking the previous/next button. I have made an example of what I want to achieve.
Here is the html:
<div ng-app="myApp" ng-controller="myCtrl">
<ul>
<li ng-repeat="t in turtles">
{{t.name}} - {{t.weapon}}
<a ng-click="show = !show">Show more</a>
<div class="modal" ng-show="show">
<div class="close" ng-click="show = !show">X</div>
{{t.name}} likes to eat {{t.food}} with his {{t.weapon}}!
<div class="previous">Previous</div>
<div class="next">Next</div>
</div>
</li>
</ul>
</div>
And the controller:
var app = angular.module('myApp', []);
app.controller('myCtrl', function ($scope) {
$scope.turtles = [
{ name: "Michellangelo", weapon: "nunchaku", food:"pizza" },
{ name: "Donatello", weapon: "bo", food:"pizza" },
{ name: "Leonardo", weapon: "katana", food:"turtle soup" },
{ name: "Rafael", weapon: "sai", food:"pizza" }
];
$scope.show=false;
});
You can see a working Jsfiddle here
回答1:
Here is a working solution: http://jsfiddle.net/s7gc81zz/5/
Instead of relying on a single variable to show or hide the modals, you can add a show attribute to each turtle, and use the $index
variable of ngRepeat to reference your position in the array:
<div ng-app="myApp" ng-controller="myCtrl">
<ul>
<li ng-repeat="t in turtles">
{{t.name}} - {{t.weapon}}
<a ng-click="showMore(t)">Show more</a>
<div class="modal" ng-show="t.show">
<div class="close" ng-click="hideMore(t)">X</div>
{{t.name}} likes to eat {{t.food}} with his {{t.weapon}}!
<div class="previous" ng-click="showPrevious(t, $index)>Previous</div>
<div class="next" ng-click="showNext(t, $index)">Next</div>
</div>
</li>
</ul>
</div>
Now you use scope functions to handle the logic of the next button:
var app = angular.module('myApp', []);
app.controller('myCtrl', function ($scope) {
$scope.turtles = [
{ name: "Michellangelo", weapon: "nunchaku", food:"pizza" },
{ name: "Donatello", weapon: "bo", food:"pizza" },
{ name: "Leonardo", weapon: "katana", food:"turtle soup" },
{ name: "Rafael", weapon: "sai", food:"pizza" }
];
//$scope.show=false;
$scope.showMore = function(turtle) {
turtle.show = true;
};
$scope.hideMore = function(turtle) {
turtle.show = false;
};
$scope.showNext = function(turtle, index) {
if((index+1) > ($scope.turtles.length - 1)) {
return;
}
else {
turtle.show = false;
$scope.turtles[index+1].show = true;
}
};
$scope.showPrevious = function(turtle, index) {
if((index-1) < 0) {
return;
}
else {
turtle.show = false;
$scope.turtles[index-1].show = true;
}
};
});
回答2:
If you want to create a navigation in the modal from next and previous buttons, then instead of having one show flag, you should have a flag on each object of the displaying array i.e turtles. And based on current looping object of ng-repeat you can then hide/ show appropriate item on next and previous buttons based on $index +1 & -1 respectively.
Here is the working Fiddle Code : http://jsfiddle.net/ashwani121/4fa6a9pr/
var app = angular.module('myApp', []);
app.controller('myCtrl', function ($scope) {
$scope.turtles = [
{ name: "Michellangelo", weapon: "nunchaku", food:"pizza" },
{ name: "Donatello", weapon: "bo", food:"pizza" },
{ name: "Leonardo", weapon: "katana", food:"turtle soup" },
{ name: "Rafael", weapon: "sai", food:"pizza" }
];
$scope.show=false;
var prevObj = null;
$scope.showModal = function(obj){
if(prevObj && prevObj.selected)
{
prevObj.selected = false;
}
obj['selected'] = true;
prevObj = obj;
}
$scope.navModal = function(index){
if(index > 0 && index < $scope.turtles.length)
$scope.showModal($scope.turtles[index]);
}
});
<div ng-app="myApp" ng-controller="myCtrl">
<ul>
<li ng-repeat="t in turtles">
{{t.name}} - {{t.weapon}}
<a ng-click="showModal(t)">Show more</a>
<div class="modal" ng-show="t.selected">
<div class="close" ng-click="show = !show">X</div>
{{t.name}} likes to eat {{t.food}} with his {{t.weapon}}!
<div class="previous" ng-click="navModal($index-1)">Previous</div>
<div class="next" ng-click="navModal($index+1)">Next</div>
</div>
</li>
</ul>
</div>
回答3:
You can use an index variable to keep track of the ninja turtle you have to show currently.
BTW you are creating unnecessary model/popup's because you only need one and you don't need a model for each of the ninja turtle :) so it is better to have only one model popup.
You can move to the next and previous ninja turtle by using the index variable you will be storing and updating it accordingly on the $scope object.
Check the code below, here the updated jsfiddle
<div ng-app="myApp" ng-controller="myCtrl">
<ul>
<li ng-repeat="t in turtles">
{{t.name}} - {{t.weapon}}
<a ng-click="showPopup($index)">Show more</a>
</li>
</ul>
<div class="modal" ng-show="show">
<div class="close" ng-click="closePopup()">X</div>
{{selectedTurtle.name}} likes to eat {{selectedTurtle.food}} with his {{selectedTurtle.weapon}}!
<div class="previous" ng-click="prev()">Previous</div>
<div class="next" ng-click="next()">Next</div>
</div>
</div>
angular
.module('myApp', [])
.controller('myCtrl', ['$scope', function ($scope) {
$scope.index = 0;
$scope.selectedTurtle = {};
$scope.turtles = [
{ name: "Michellangelo", weapon: "nunchaku", food:"pizza" },
{ name: "Donatello", weapon: "bo", food:"pizza" },
{ name: "Leonardo", weapon: "katana", food:"turtle soup" },
{ name: "Rafael", weapon: "sai", food:"pizza" }
];
$scope.show = false;
$scope.showPopup = showPopup;
$scope.closePopup = closePopup;
$scope.next = next;
$scope.prev = prev;
function setTurtle(index) {
$scope.selectedTurtle = $scope.turtles[index];
}
function showPopup(index) {
$scope.index = index;
setTurtle($scope.index);
$scope.show = true;
}
function closePopup() {
$scope.show = false;
}
function next() {
if ($scope.index !== $scope.turtles.length - 1) {
$scope.index++;
setTurtle($scope.index);
}
}
function prev() {
if ($scope.index !== 0) {
$scope.index--;
setTurtle($scope.index);
}
}
}]);
回答4:
as you maybe already noticed ng-show just add/remove a css class. So based on this, you should give an ID to your DIVs, maybe using the internal var $index from the ng-repeat directive, for example id="card-{{$index}}". Having identified your DIVs and with a little jquery help (it also can be done with just plain js) you can identify the active card, check its ID, calculate the next or previous ID value, and add or remove any particular css class you need.
Or you can just look for an angular carousel ;)
来源:https://stackoverflow.com/questions/36629423/angularjs-go-to-previous-next-modal