Добавляйте класс только к конкретному ng-repeat в AngularJS

У меня в приложении есть система, похожая на стиль Facebook, и я хочу, чтобы кнопка «Нравится» меняла цвет при нажатии пользователем. Это нужно сделать, добавив класс .active, но я не могу понять, как получить только один элемент в моем ng-repeat, чтобы иметь активный класс.

Вот мой взгляд:

<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>

ng-click отправляет запрос на сервер для сохранения в базе данных, а ng-класс изменяет класс на активный, когда переменная «фаворит» из контроллера изменяется на true после того, как этот запрос будет успешным:

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

Это приводит к тому, что все любимые кнопки становятся активными, поэтому я просто не знаю, как сделать активной только текущую кнопку.

заранее спасибо


person JamesG    schedule 02.04.2016    source источник


Ответы (4)


Это связано с тем, что вы используете $scope.favorited, поскольку существует только одна копия этой переменной для всех ng-повторов, поэтому она обновляется для всех. Поэтому попробуйте использовать некоторую переменную для отдельной записи в соответствии с вашими требованиями, поскольку вы хотите отметить только одну запись как избранную за раз.

Заменять

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

и

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

person Harpreet    schedule 02.04.2016

Вы не можете использовать глобальное логическое значение, чтобы сказать, что конкретный элемент массива является любимым.

Вместо сохранения логического значения в области действия сохраните элемент, который является избранным, и используйте active: data == theFavoriteElement.

Или, если в избранное можно добавить несколько элементов, сохраните логическое значение в самом элементе и используйте active: data.favorite.

person JB Nizet    schedule 02.04.2016

Просто установите свойство favorite для каждого элемента data. И как только ваш запрос будет успешно выполнен, измените свойство favorite ваших данных, а не свойство $scope.

<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>

И в вашем контроллере:

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

Это должно сработать, но если вы хотите сохранить избранные данные, вам нужно связать модель с данными из бэкэнда. например, если флаг сохранен в data, вы должны изменить

<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>
person Zhiliang Xing    schedule 02.04.2016