简体   繁体   English

根据 AngularJS 中的条件从数组中添加和删除项目

[英]Adding and removing items from arrays, based on a condition in AngularJS

I'm trying to make a dynamic "favorites" toggle-button.我正在尝试制作一个动态的“收藏夹”切换按钮。 When clicking the button, it should add the selected player to the users favorite-list.单击该按钮时,它应该将选定的播放器添加到用户的收藏夹列表中。 If the player is already favorited, it should remove it.如果播放器已被收藏,则应将其删除。

I've also tried to iterate through the favorites, to check if a player is already favorited.我还尝试遍历收藏夹,以检查玩家是否已被收藏。 If true, it colors the favorite star gold.如果为真,它会将最喜欢的星星涂成金色。

A few problems here.这里有几个问题。 My for loop for checking seems to be working properly as long as the array only contains one item.只要数组只包含一项,我的 for 循环检查似乎就可以正常工作。 But as soon as I try adding more, the gold icon is only gold colored on the last player added to favorites.但是,一旦我尝试添加更多内容,金色图标就只是添加到收藏夹的最后一个玩家的金色图标。 So the check only finds one favorite at a time, and I can add a player to favorites many times, as long as I vary the players I add.所以检查一次只能找到一个最喜欢的,我可以多次将一个球员添加到我的最爱,只要我改变我添加的球员。

If someone could point me in the right direction and help me understand why my loop isn't working correctly, that would be awesome!如果有人能指出我正确的方向并帮助我理解为什么我的循环不能正常工作,那就太棒了!

http://codepen.io/utrolig/pen/LNgRwv http://codepen.io/utrolig/pen/LNgRwv

Javascript Javascript

angular.module('test', [])

  .controller('TestController', function($scope){
    $scope.players = [
      {
        uniqueid: "gem",
        name: "Ole Christian",
        cake: false,
      },{
        uniqueid: "utrolig",
        name: "Stian",
        cake: false,
      },{
        uniqueid: "drozo",
        name: "Adrian",
        cake: false,
      }
    ];

    $scope.user = {
      name: "Stian",
      username: "stiba",
      favorites: [{uniqueid: "drozo"}],
    }

    $scope.checkFavorite = function(id){
      fav = $scope.user.favorites;
      var exists;
      for (var i=0; i < fav.length; i++){
        if(fav[i].uniqueid == id){
          exists = true;
        } else {
          exists = false;
        } 
      }
      return exists;
    }

    $scope.toggleFavorite = function(id){
      fav = $scope.user.favorites;
      if(fav.length === 0){
        var newfav = {uniqueid: id};
        fav.push(newfav);
      } else {
         if($scope.checkFavorite(id) === true){
          for(var i = 0; i < fav.length; i++){
             if (fav[i].uniqueid === id) fav.splice(i, 1);
          }
        } else if ($scope.checkFavorite(id) === false) {
          var newfav = {uniqueid: id};
          fav.push(newfav)
        } else {
          console.log('Error!');
        } 
      }
    }

    $scope.isFavorited = function(){
      return true;
    };

  })

HTML HTML

<body ng-app="test">
  <div class="container" ng-controller="TestController">
    <h3>Players</h3>
    <div ng-repeat="player in players" class="player-cont">
      <div class="player">
        <div class="favorite" ng-click="toggleFavorite(player.uniqueid)" ng-class="{'active': checkFavorite(player.uniqueid)}">
          <i class="material-icons">star</i>
        </div>
        <i class="material-icons player-icon">person</i>
      </div>
      <div>
        <p ng-bind="player.uniqueid"></p>
        <p ng-bind="player.name"></p>
      </div>
    </div>
    <h3>Favorites</h3>
    <div ng-repeat="favorite in user.favorites track by $index">
      <h5>{{favorite.uniqueid}}</h5>
    </div>
    <p class="user">
    {{user.favorites}}
    </p>
  </div>

</body>

There's a couple of errors in your code.您的代码中有几个错误。

The first is checkFavorite , if you examine the code you'll see that only the last item is actually compared to id , since the exists flag is updated for each item.第一个是checkFavorite ,如果您检查代码,您会发现实际上只有最后一个项目与id进行比较,因为每个项目的exists标志都会更新。 You need to "short circuit" the loop and return true as soon as you find a value.您需要“短路”循环并在找到值后立即返回 true。

btw, is* is a common name convention for checking boolean values.顺便说一句, is*是用于检查布尔值的通用名称约定。

$scope.isFavorite = function(id){
  var fav = $scope.user.favorites;
  for (var i=0; i < fav.length; i++){
    if(fav[i].uniqueid == id){
      return true;
    }
  }
  return false;
}

Your toggle is also very verbose, if you "reduce" the code you end up with something like this你的切换也很冗长,如果你“减少”代码,你最终会得到这样的东西

$scope.toggleFavorite = function(id){
  var fav = $scope.user.favorites;
  // no previous items, remove, OK
  if(fav.length === 0) {
    var newfav = {uniqueid: id};
    fav.push(newfav);
    return;
  }

  // if already a favorite, uncheck/remove
  if($scope.isFavorite(id)) {
    for(var i = 0; i < fav.length; i++){
       if (fav[i].uniqueid === id) fav.splice(i, 1);
    }
  }
  // otherwise add the item
  // remember, isFavorite returns true of false, there is no third state
  else { // if ($scope.isFavorite(id) === false) {
    var newfav = {uniqueid: id};
    fav.push(newfav)
  }
}

This can be edited further, since the isFavorite function will return false if the list is empty, ie no need for the first if这可以进一步编辑,因为如果列表为空,isFavorite 函数将返回 false,即不需要第一个if

$scope.toggleFavorite = function(id){
  var fav = $scope.user.favorites;
  // if already a favorite, uncheck/remove
  if($scope.isFavorite(id)) {
    for(var i = 0; i < fav.length; i++){
       if (fav[i].uniqueid === id) {
         fav.splice(i, 1);
         // unless the item exists more than once, break the loop
         break;
       }
    }
  }
  // otherwise add the item
  else {
    var newfav = {uniqueid: id};
    fav.push(newfav)
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM