如何搜索特定对象属性的对象数组

时间:2017-03-20 15:37:52

标签: angularjs web-applications

以下是我的代码的链接:

https://www.w3schools.com/code/tryit.asp?filename=FDTQ99YQS60B

如何让用户只能购买2名玩家“Defender”?换句话说,如何让用户只能购买每个位置的2个物体?

2 个答案:

答案 0 :(得分:1)

我使用Array.prototype.reduce来解决您的问题。希望这会有所帮助。

var selected = $scope.history.reduce(function(a,b){
    a[b.position] = (a[b.position] || 0) + 1;
    return a;
}, {}) || {};

//{defender:1, forward: 2, midfielder:1}

此块计算每个玩家位置的附加计数。如果没有添加任何玩家,则selected将默认为{}。另外,我正在将player对象而不是$index传递给buy方法。

因此,以下条件会检查为每个玩家位置添加的玩家数量。

if(!selected[player.position] || selected[player.position]<2){
    $scope.history.push(player);
}else{
    alert('You can add only two players per position');
}

此处player.position来自传递给player方法的buy对象。

所以,比方说,

selected = {defender:1, forward: 2, midfielder:1};

player传递给buy方法,

player = {name : "Chinedu 'Anuxx' Anukwem", Team : "FBGFC", price: 8000000, position:'forward',image: src='http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'};

console.log(selected[player.position]) // 2

var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope, PlayerService) {
    $scope.playersSelected = "0/6";
    $scope.total = 50000000;
    //keep trak of what was bought already
    $scope.history = PlayerService.getSelectedPlayers();
    $scope.denteries = [];
    $scope.players = [{
        name: "Yasin 'YB' Amusan",
        Team: "Industry",
        price: 8000000,
        position: 'forward',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Hassan 'Hasi' Akinyera",
        Team: "Industry",
        price: 5000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Femi 'Fabio' Awoniyi",
        Team: "Industry",
        price: 9000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Deji 'Dej' Awoniyi",
        Team: "Industry",
        price: 7000000,
        position: 'forward',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Koye 'K10' Kekere-Ekun",
        Team: "Industry",
        price: 9000000,
        position: 'midfielder',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Teni 'Teezee' Zacchaeus",
        Team: "Industry",
        price: 6000000,
        position: 'hybrid',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Bolaji 'Boj' Odojukan",
        Team: "Industry",
        price: 7000000,
        position: 'forward',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Ernest",
        Team: "Industry",
        price: 6000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Fikayo 'Kyo' Etti",
        Team: "Industry",
        price: 8000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Efe Tunde-Imoyo",
        Team: "Industry",
        price: 5000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Temi 'Forbes' Afolabi",
        Team: "VGC",
        price: 14000000,
        position: 'forward',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Dami Etomi",
        Team: "VGC",
        price: 7000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Tomi 'Belg' Belgore",
        Team: "VGC",
        price: 8000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Tobi 'Staxx' Kasali",
        Team: "VGC",
        price: 9000000,
        position: 'Hybrid',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Bobo",
        Team: "VGC",
        price: 9000000,
        position: 'Hybrid',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Ola Adeyemi",
        Team: "VGC",
        price: 5000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Pekun 'Pyzzle' Odutola",
        Team: "VGC",
        price: 9000000,
        position: 'Hybrid',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Oreva 'Revz' Amata",
        Team: "VGC",
        price: 11000000,
        position: 'forward',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Tenny 'TK' Karim",
        Team: "YMFC",
        price: 5000000,
        position: 'Forward',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Andy Inegbese",
        Team: "YMFC",
        price: 5000000,
        position: 'Midfielder',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Donald 'DO' Ofik",
        Team: "YMFC",
        price: 7000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Zachy Mbadiwe",
        Team: "YMFC",
        price: 10000000,
        position: 'Forward',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Emeke 'Mexxo'",
        Team: "YMFC",
        price: 6000000,
        position: 'midfielder',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Ife 'I-Baxx Bakare",
        Team: "YMFC",
        price: 6000000,
        position: 'midfielder',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Gabriel 'Gabby' Inegbese",
        Team: "YMFC",
        price: 8000000,
        position: 'Hybrid',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Jimi Oyelola",
        Team: "YMFC",
        price: 5000000,
        position: 'Forward',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Chad 'Chadea' Oyefolu",
        Team: "ChadFC",
        price: 5000000,
        position: 'Forward',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Ekoh 'Starboy' Sagoe",
        Team: "ChadFC",
        price: 15000000,
        position: 'midfielder',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Tomiwa 'JBET' Jaiyeola",
        Team: "ChadFC",
        price: 13000000,
        position: 'Forward',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Lemar Chris",
        Team: "ChadFC",
        price: 9000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Olumide 'Olic' Williams",
        Team: "ChadFC",
        price: 7000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Leke 'LVD' Dokomu",
        Team: "ChadFC",
        price: 7000000,
        position: 'midfielder',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Dola Awosika",
        Team: "ChadFC",
        price: 5000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Nehemiah 'Memphis'",
        Team: "ChadFC",
        price: 7000000,
        position: 'midfielder',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Kola 'Skippo' Ayanwale",
        Team: "ChadFC",
        price: 10000000,
        position: 'midfielder',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Milekan 'Mileks'",
        Team: "ChadFC",
        price: 7000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Lanre 'Lavigz' Vigo",
        Team: "ChadFC",
        price: 8000000,
        position: 'hybrid',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Alfred 'Flyz' Obande",
        Team: "FBGFC",
        price: 6000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Chuka 'Zingy' Azinge",
        Team: "FBGFC",
        price: 6000000,
        position: 'hybrid',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Osobase 'Oso' OmoKhodion",
        Team: "FBGFC",
        price: 10000000,
        position: 'midfielder',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Arnold Okuguni",
        Team: "FBGFC",
        price: 7000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Ikenna Mbadiwe",
        Team: "FBGFC",
        price: 6000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Moukhtar",
        Team: "FBGFC",
        price: 8000000,
        position: 'forward',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Chinedu 'Anuxx' Anukwem",
        Team: "FBGFC",
        price: 8000000,
        position: 'forward',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Tosan 'Mac' Wiltshere",
        Team: "FBGFC",
        price: 6000000,
        position: 'defender',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      },
      {
        name: "Martin Agbaso",
        Team: "FBGFC",
        price: 5000000,
        position: 'forward',
        image: src = 'http://res.cloudinary.com/deji/image/upload/v1489787662/blank_photo_mqvivv.png'
      }
    ];

    $scope.buy = function(player) {
      //remove if already added
      if(PlayerService.removePlayerFromSelection(player)){
        return;
      }

      //max 6 allowed
      if ($scope.history.length >= 6) {
        alert('max 6 allowed');
        return;
      }

      var selected = $scope.history.reduce(function(a, b) {
        a[b.position] = (a[b.position] || 0) + 1;
        return a;
      }, {}) || {};

      if (!selected[player.position] || selected[player.position] < 2) {
        PlayerService.addPlayerToSelection(player);
      } else {
        alert('You can add only two players per position');
      }
    };

    $scope.getTotal = function() {
      return $scope.history.reduce(function(tot, p) {
        tot = tot - p.price;
        return tot;
      }, $scope.total);
    };
  })
  .factory('PlayerService', function() {
    var service = {};
    var _data = {
      selectedPlayers: []
    };

    service.getSelectedPlayers = function() {
      return _data.selectedPlayers;
    };

    service.setSelectedPlayers = function(players) {
      //to maintain the array reference we are doing this, othewise we can directly assign players to selectedPlayers
      _data.selectedPlayers.splice(0, _data.selectedPlayers.length);
      players.forEach(function(player) {
        _data.selectedPlayers.push(player);
      });
    };

    service.addPlayerToSelection = function(player) {
      return _data.selectedPlayers.push(player);
    };

    service.removePlayerFromSelection = function(player) {
      var index = _data.selectedPlayers.indexOf(player);
      if (index >= 0) {
        _data.selectedPlayers.splice(index, 1);
        return true;
      }
      return false;
    };

    return service;
  })
  .controller('TestCtrl', function($scope, PlayerService){
    $scope.selectedPlayers = PlayerService.getSelectedPlayers();
  });
div[ng-controller]{
  float:left;
  box-sizing:border-box;
  width:50%;
}
<head>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
  <link href="app.css" rel="stylesheet" type="text/css" />
  <title>TNF FANTASY</title>
</head>


<div class="app" ng-app="myApp">
<div ng-controller="myCtrl">

  <div class="total"><i>  <h4> Money Remaining: <br>{{getTotal() |currency}}</h4></i>
    <h4>{{history.length}}/6</h4>

  </div>

  <ul>
    <li class="players" ng-repeat="player in players">


      {{player.name}} <br> {{player.Team}} <br> {{player.price| currency}} <br> {{player.position| uppercase }}
      <br>
      <button ng-click="buy(player)">{{history.indexOf(player)>=0?'remove':'buy'}}</button>
    </li>
  </ul>
  </div>
  <div ng-controller="TestCtrl">
    <h1>Selected player accessed in another controller:</h1>
    
    <pre>{{selectedPlayers | json}}</pre>
  </div>
</div>

答案 1 :(得分:0)

你可以做的是在将玩家添加到$scope.history阵列之前,检查该位置是否已经选择了2个玩家。