If you want to ensure only one item is selected at a time, utilize selectedItem in the $scope and apply ng-if in the template to verify if the chosen item matches the current item. See the example below:
angular.module('myApp', [])
.controller('MainController', function ($scope) {
var items = [],
vm = {};
// properties
$scope.vm = vm;
vm.items = items;
vm.selectedItem = null;
//methods
vm.setItem = function (item) {
// reset current item to more
if (vm.selectedItem) {
vm.selectedItem.detailsText = 'More';
}
// collapse if selecting same item
if (item === vm.selectedItem) {
vm.selectedItem = null;
return;
}
item.detailsText = 'Less';
vm.selectedItem = item;
};
activate();
// initialization logic
function activate() {
for(var i = 0; i < 15; ++i) {
items.push({id: i, title: 'Item: ' + i, details: 'Item ' + i + ' Details', detailsText: 'More'});
}
}
});
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
a {
color: #004b8d;
text-decoration: underline;
cursor: pointer;
}
a:hover {
color: #2c88e6;
text-decoration: none;
}
.container {
width: 500px;
border: 1px solid black;
}
.item {
padding: 12px;
border-bottom: 1px solid gray;
}
.item:last-child {
border: 0;
}
.details {
margin-left: 10px;
color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MainController" class="container">
<div class="item" ng-repeat="item in vm.items">
{{item.title}} <a ng-click="vm.setItem(item)">{{item.detailsText}}</a>
<div class="details" ng-if="vm.selectedItem === item">
{{item.details}}
</div>
</div>
</div>
This approach simplifies updates through the controller and template, eliminating the need to duplicate sections of the template for deactivation. All logic resides directly within the controller, facilitating unit tests. For instance:
it('should update selected item', function () {
// ... initialize controller and $scope properties
var item = {};
$scope.vm.setItem(item);
expect($scope.vm.selectedItem).toBe(item);
expect(item.detailsText).toBe('Less');
});