AngularJS NgRepeat + NgClass
by JakobJingleheimer
HTML
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.9/angular.js"></script>
<div ng-controller="MyController">
<p>{{mem}}</p>
<ul>
<li ng-class="{'active': $parent.mem.A == $key, 'not-active': $parent.mem.A && $parent.mem.A != $key}" ng-repeat="($key, A) in As" ng-click="$parent.mem.A = $key">
<p>{{A.x}}</p>
<button ng-click="$parent.mem.A = $parent.findInHash($event,'prev','A')">Activate previous</button>
</li>
</ul>
</div>
<pre>
Instructions:
1. Click any row
2. Click its 'Activate previous' button.
The `findInHash` function returns the correct value, yet the scope value does not change.
</pre>
CSS
li {
cursor: pointer;
}
pre {
margin: 1em 0;
word-wrap: break-word;
}
li:nth-child(odd) {
background: #ccc;
}
li:nth-child(even) {
background: #666;
color: white;
}
.active {
background: red !important;
}
.not-active {
opacity: 0.5;
}
JavaScript
angular.module('MyApp', [])
.controller('MyController', [
'$scope',
function MyController($scope) {
$scope.mem = {
A: '',
B: '',
C: ''
};
$scope.As = {
bar: { x: 'bar-x', y: 'bar-y', z: 'bar-z' },
foo: { x: 'foo-x', y: 'foo-y', z: 'foo-z' },
qux: { x: 'qux-x', y: 'qux-y', z: 'qux-z' }
};
$scope.Bs = {};
$scope.Cs = {};
$scope.findInHash = function ($event, dir, attr) {
$event.stopPropagation();
$event.preventDefault();
var hash = $scope[attr+'s'],
current = $scope.mem[attr],
keys = Object.keys(hash),
i = keys.indexOf(current),
n = keys.length-1;
if (dir === 'prev') {
console.log('prev');
if (i > 0) {
return keys[i - 1];
}
return keys[n]; // the last key
} else {
if (i !== n) {
return keys[i + 1];
}
return keys[0];
}
};
}]);