Reputation: 63647
A series of links apple, orange, banana
are created using ng-repeat
. Clicking on these links will cause that fruit's color to appear below the link.
Problem: However when any link is clicked, the colors for all the fruits are shown. How can we restrict the click event to only show the color of the fruit that is clicked?
Jsfiddle: http://jsfiddle.net/hut13fox/
HTML
<div ng-controller="FruitCtrl">
<div ng-repeat="f in fruits">
<a href="#" ng-click="toggleShow()">{{ f.title }}</a>
<div ng-show="show">
{{ f.color }}
</div>
</div>
</div>
JS
var myApp = angular.module('myApp', []);
FruitCtrl = function($scope) {
$scope.fruits = [
{ title: 'apple', color: 'red' },
{ title: 'orange', color: 'orange' },
{ title: 'banana', color: 'yellow' }
];
$scope.show = false
$scope.toggleShow = toggleShow
function toggleShow() {
console.log('toggle')
$scope.show = !$scope.show
}
}
console.log('Hello')
Upvotes: 6
Views: 523
Reputation: 52847
I would do this which doesn't require you to modify your model:
<div ng-controller="FruitCtrl">
<div ng-repeat='f in fruits'>
<a href="#" ng-click='show=!show'>{{ f.title }}</a>
<div ng-show='show'>
{{ f.color }}
</div>
</div>
</div>
The reason this works is because an ngRepeat will create a child scope with each iteration. By using the expression show=!show
, it ensures that the expression is evaluated against the current iteration's child scope, and each child scope gets its own "show" scope property.
Upvotes: 3
Reputation: 25797
Change your code something like this:
<div ng-controller="FruitCtrl">
<div ng-repeat="f in fruits">
<a href="#" ng-click="toggleShow(f)">{{ f.title }}</a>
<div ng-show="f.show">
{{ f.color }}
</div>
</div>
</div>
And your JS to
function toggleShow(f) {
console.log('toggle')
f.show = !f.show
}
Basically, you were previously using a common scope show
for all items which was causing the problem. And now we are using each fruit items separately to toggle each item using f.show
by maintaining a key show
in your each fruit item.
See a working code here:
var myApp = angular.module('myApp', []);
FruitCtrl = function($scope) {
$scope.fruits = [{
title: 'apple',
color: 'red'
}, {
title: 'orange',
color: 'orange'
}, {
title: 'banana',
color: 'yellow'
}];
$scope.show = false
$scope.toggleShow = toggleShow
function toggleShow(f) {
console.log('toggle')
f.show = !f.show
}
}
myApp.controller('FruitCtrl', FruitCtrl);
console.log('Hello')
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="FruitCtrl">
<div ng-repeat='f in fruits'>
<a href="#" ng-click='toggleShow(f)'>{{ f.title }}</a>
<div ng-show='f.show'>
{{ f.color }}
</div>
</div>
</div>
</div>
Upvotes: 1
Reputation: 1203
You should set the visibility in each element
<div ng-controller="FruitCtrl">
<div ng-repeat='fruit in fruits'>
<a href="#" ng-click='toggleShow(fruit)'>{{ fruit.title }}</a>
<div ng-show='fruit.show'>
{{ fruit.color }}
</div>
</div>
</div>
And format your JS like
function toggleShow(fruit) {
fruit.show = fruit.show
}
Your object will be something like:
$scope.fruits = [
{ title: 'apple', color: 'red', show : true },
{ title: 'orange', color: 'orange', show : true },
{ title: 'banana', color: 'yellow', show : true }
];
This way you can control the defaults
Also, you don't necessarily need the toggle method, you can do it inline in the html tag:
<a href="#" ng-click='fruit.show = !fruit.show'>{{ fruit.title }}</a>
Upvotes: 3