J.Rem
J.Rem

Reputation: 545

Angular update object in array on ng-click?

On the snippet below each cell contains the name of a shape that are taken from a given sequence. I'm trying to update the shape name of the selected cell on ng-click="fadeName(card)", however, when clicking it does update all cells with the same shape name.For instance, if you click row1,col1 which is by default square, all other squares will be updated, I only want to update the selected one. How can I update only the selected cell value ?

// constant variables 
var constants = new (function() {
    var rows = 10;
    var columns = 10;
    this.getRows = function() { return rows; };
    this.getColumns = function() { return columns; };
   
})();

// Global Variables
var shapeSequence = 
  [
    {id: '1', name:'square'},
    {id: '2', name:'triangle'},
    {id: '3', name:'circle'},
    {id: '4', name:'oval'},
    {id: '5', name:'pentagon'},
    {id: '6', name:'hexagon'},
    {id: '7', name:'decagon'},
  ]


// this function creates deck of cards that returns an object of cards 
function createDeck() {
	var rows = constants.getRows();
	var cols = constants.getColumns();
	var key = createColors();
  
	var deck = {};
	deck.rows = [];

	// create each row
	for(var i = 0; i < rows; i++) {
		var row = {};
		row.cards = [];
		
		// creat each card in the row
		for (var j = 0; j < cols; j++) {
			var card = {};
			card.item = key.shift();
			row.cards.push(card);
		}
		deck.rows.push(row);
	}
	return deck;
}


function createColors() {
	var coloredCards = [];
	
  var rows = constants.getRows();
	var cols = constants.getColumns();

  var cells = rows * cols;
	for (var n = 0; n < cells; n++) {
    var thisCard = shapeSequence[n % shapeSequence.length];
    coloredCards.splice(n, 0, thisCard);
	}
  
	return coloredCards;
 
} 

var app = angular.module('cards', ['ngAnimate']);

app.controller("CardController", function($scope) {
	$scope.deck = createDeck();
  $scope.fadeName = function(card) {
    card.item.name = 'black';
  }
  
  
}); 
.card_container {
  position: relative;
  width: 50px;
  height: 50px;
  text-align: center;
  vertical-align: middle;
  line-height: 50px;
  z-index: 1; 
  font-size: 1em;
  border:solid 1px;
  border-color:black;

}

.card_container {
  -moz-perspective: 1000;
  -webkit-perspective: 1000;
  perspective: 1000;
} 

.card {
  width: 100%;
  height: 100%;
  cursor: pointer;
}


table {
	margin: 0px auto;
  
}

.cntr {
  margin: 15px auto;
}
<html ng-app="cards">
	<head>
		<meta charset="utf-8">
		<link rel="stylesheet" href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
	
		<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js" type="text/javascript"></script>
		<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular-animate.min.js" type="text/javascript"></script>
	</head>
<body>
	<div class="cntr" ng-controller="CardController">
		<table >
			<tr ng-repeat="row in deck.rows">
				<td ng-repeat="card in row.cards">
					<div class="card_container " >
						<div class="card " ng-click="fadeName(card)"  ng-mouseenter="hover = true" ng-mouseleave="hover = false" >
              <p ng-if="hover"> {{card.item.name}} </p>
						</div>
					</div>
				</td>
			</tr>
		</table>

	</div>
</html>

Upvotes: 0

Views: 840

Answers (2)

Sagar Kamble
Sagar Kamble

Reputation: 590

You added reference from shapeSequence into your cells where you updated one cells data that will reflect everywhere where you used the same reference. So I only created clone while creating colors in 'createColors()'. clone() is also added.

// constant variables 
var constants = new (function() {
    var rows = 10;
    var columns = 10;
    this.getRows = function() { return rows; };
    this.getColumns = function() { return columns; };
   
})();

function clone(obj) {
    if (null == obj || "object" != typeof obj) return obj;
    var copy = obj.constructor();
    for (var attr in obj) {
        if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
    }
    return copy;
}

// Global Variables
var shapeSequence = 
  [
    {id: '1', name:'square'},
    {id: '2', name:'triangle'},
    {id: '3', name:'circle'},
    {id: '4', name:'oval'},
    {id: '5', name:'pentagon'},
    {id: '6', name:'hexagon'},
    {id: '7', name:'decagon'},
  ]


// this function creates deck of cards that returns an object of cards 
function createDeck() {
	var rows = constants.getRows();
	var cols = constants.getColumns();
	var key = createColors();
  
	var deck = {};
	deck.rows = [];

	// create each row
	for(var i = 0; i < rows; i++) {
		var row = {};
		row.cards = [];
		
		// creat each card in the row
		for (var j = 0; j < cols; j++) {
			var card = {};
			card.item = key.shift();
			row.cards.push(card);
		}
		deck.rows.push(row);
	}
	return deck;
}


function createColors() {
	var coloredCards = [];
	
  var rows = constants.getRows();
	var cols = constants.getColumns();

  var cells = rows * cols;
	for (var n = 0; n < cells; n++) {
    var thisCard = shapeSequence[n % shapeSequence.length];
    coloredCards.splice(n, 0, clone(thisCard));
	}
  
	return coloredCards;
 
} 

var app = angular.module('cards', ['ngAnimate']);

app.controller("CardController", function($scope) {
	$scope.deck = createDeck();
  $scope.fadeName = function(card) {
    card.item.name = 'black';
  }
  
  
});
.card_container {
  position: relative;
  width: 50px;
  height: 50px;
  text-align: center;
  vertical-align: middle;
  line-height: 50px;
  z-index: 1; 
  font-size: 1em;
  border:solid 1px;
  border-color:black;

}

.card_container {
  -moz-perspective: 1000;
  -webkit-perspective: 1000;
  perspective: 1000;
} 

.card {
  width: 100%;
  height: 100%;
  cursor: pointer;
}


table {
	margin: 0px auto;
  
}

.cntr {
  margin: 15px auto;
}
<html ng-app="cards">
	<head>
		<meta charset="utf-8">
		<link rel="stylesheet" href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
	
		<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js" type="text/javascript"></script>
		<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular-animate.min.js" type="text/javascript"></script>
	</head>
<body>
	<div class="cntr" ng-controller="CardController">
		<table >
			<tr ng-repeat="row in deck.rows">
				<td ng-repeat="card in row.cards">
					<div class="card_container " >
						<div class="card " ng-click="fadeName(card)"  ng-mouseenter="hover = true" ng-mouseleave="hover = false" >
              <p ng-if="hover"> {{card.item.name}} </p>
						</div>
					</div>
				</td>
			</tr>
		</table>

	</div>
</html>

Upvotes: 0

While pushing to row

do

card = JSON.parse(JSON.stringify(card));
row.cards.push(card);

Upvotes: 1

Related Questions