Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ng-click function affecting all ng-repeat elements

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')
like image 204
Nyxynyx Avatar asked Dec 16 '15 07:12

Nyxynyx


2 Answers

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>
like image 149
Lucas Rodriguez Avatar answered Oct 14 '22 00:10

Lucas Rodriguez


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.

like image 29
pixelbits Avatar answered Oct 14 '22 00:10

pixelbits