Only add class to specific ng-repeat in AngularJS

2019-07-15 08:59发布

问题:

I have a Facebook style like system in my app and I want to make the like button change colour when the user clicks. This is to be done by adding an .active class, but I cant figure out how to get just the one item in my ng-repeat to have thr active class.

Heres my view:

<div class="list card" ng-repeat="data in array">
  <div>
    <a ng-click="favourite(data.ID)" class="tab-item" >
      <i ng-class="{'active':  favourited}" class="icon ion-thumbsup" ></i>
      Favourite
    </a>
  </div>
</div>

The ng-click sends the request to the server to store in the database, and the ng-class changes the class to active when the "favourite" variable from the controller changes to true once this request is sucesfull:

$scope.favourite = function(dataID){
    $favourite.favourite(dataID).then(function(data){
      $scope.favourited = true;
    });
  }

This causes all of the favourite buttons to become active, so I just dont know how to make just the current button active.

Thanks in advance

回答1:

This is because you are using $scope.favourited as there is only single copy of this variable for all ng-repeats, hence it updates for all. So try to use some variable for individual record as per your requirement as you only want to mark a single record as favourite at a time.

Replace

ng-class="{'active': favourited}" with ng-class="{'active': data.favourited}"

and

$scope.favourited = true; with data.favourited = true;



回答2:

You can't use a global boolean to say that a specific element of an array is the favorite one.

Instead of storing a boolean in the scope, store the element that is the favorite, and use active: data == theFavoriteElement.

Or, if several elements can be favorite, store a boolean in the element itself, and use active: data.favorite.



回答3:

Just set the favorite property on each of your data element. And once your request is successfully completed, change the favorite property of your data and not the $scope's property.

<div class="list card" ng-repeat="data in array">
  <div>
    <a ng-click="favourite(data.ID)" class="tab-item" >
      <i ng-class="{'active':  data.favorited}" class="icon ion-thumbsup" ></i>
      Favourite
   </a>
  </div>
</div>

And in your controller:

$scope.favourite = function(dataID){
    $favourite.favourite(dataID).then(function(data){
        data.favourited = true;
    });
}


回答4:

This should do the job, but if you want the favorite data to preserve, then you have to bind the model with the data from backend. for example, if the flag is saved in data, you should change

<div>
  <a ng-click="active = !active" class="tab-item" ng-model="active" >
    <i ng-class="{'active': active}" class="icon ion-thumbsup" ></i>
      Favourite
  </a>
</div>

to

<div>
  <a ng-click="favorite(data)" class="tab-item">
    <i ng-class="{'active': data.active}" class="icon ion-thumbsup" ></i>
      Favourite
  </a>
</div>

$scope.favorite = function(data) {
    //use $http or $resource to update the data in backend
    //for example if you used $resource service
    data.favorite = !data.favorite;
    data.$save();
};

============

<!DOCTYPE html>
<html ng-app="test">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body ng-controller="testCtrl">
<div class="list card" ng-repeat="data in a">
  <div>
    <a ng-click="active = !active" class="tab-item" ng-model="active" >
      <i ng-class="{'active': active}" class="icon ion-thumbsup" ></i>
      Favourite
    </a>
  </div>
</div>
</body>
</html>