如何添加嵌套数组的属性

How to add up the attribute of a nested array

我的逻辑没有问题。

我有一个手风琴,我拍了张照片

headers LIVE BETTING、MLB、MLB Props 和 NBA 都在 HTML 中(实际上是将近 25 项的体育项目列表)

  <accordion>
    <accordion-group ng-repeat="sport in sports">
      <accordion-heading>
        <div ng-click="addSportToLines(sport);">
          <span>{{sport.name}}</span>
          <span class="badge">{{sport.leagues.length}}</span>
        </div>
      </accordion-heading>

      <div>
        <a ng-repeat="league in sport.leagues"
           ng-click="addLeagueToLines(league)">
           <span>{{league.name}}</span>
           <span class="badge">{{league.offeringsAvailable}}</span>
        </a>
      </div>
    </accordion-group>
  </accordion>

我需要删除包含 {{sport.leagues.length}} 的第一个 <span class=badge> 并将 {{league.offeringsAvailable}} 的总和放在那里。 {{league.offeringsAvailable}} 是灰色的数字 badge,正如您在 MLB 中看到的那样:72,30,30,8,30

所以在黄色徽章中,我需要 league.offeringsAvailable

的总和,而不是 sport.leagues.length

这是 sports

的控制器
SportsFactory.getSportsWithLeagues().then(function(sports) {
  $scope.sports = sports;
  console.log(angular.toJson($scope.sports, 'pretty'));
});

有了这个 console.log(angular.toJson($scope.sports, 'pretty')); 我明白了 json

如您所见,header,例如:LIVE BETTING,这是第一个,包含一个数组 leagues 和一个名为 offeringsAvailable 的道具,所以我需要采取让我们说每一个 offeringsAvailable 里面的现场投注,并将总金额放入 $scope 变量中,以便在 DOM.

中显示
[
  {
    "id": 26,
    "name": "LIVE BETTING",
    "priority": 0,
    "leagues": [
      {
        "id": "3042",
        "composedId": "3042G",
        "name": "NBA - Live",
        "lineType": "G",
        "part": 0,
        "offeringsAvailable": 3,
        "sport": {
          "id": 26
        }
      },
      {
        "id": "3042",
        "composedId": "3044Q",
        "name": "NBA - Live (2Q)",
        "lineType": "Q",
        "part": 2,
        "offeringsAvailable": 2,
        "sport": {
          "id": 26
        }
      },
      {
        "id": "3042",
        "composedId": "3045Q",
        "name": "NBA - Live (3Q)",
        "lineType": "Q",
        "part": 3,
        "offeringsAvailable": 2,
        "sport": {
          "id": 26
        }
      },
      {
        "id": "3042",
        "composedId": "3046Q",
        "name": "NBA - Live (4Q)",
        "lineType": "Q",
        "part": 4,
        "offeringsAvailable": 2,
        "sport": {
          "id": 26
        }
      },
      {
        "id": "3068",
        "composedId": "3068G",
        "name": "Soccer - Live",
        "lineType": "G",
        "part": 0,
        "offeringsAvailable": 41,
        "sport": {
          "id": 26
        }
      },
      {
        "id": "3295",
        "composedId": "3295G",
        "name": "MLB - Live",
        "lineType": "G",
        "part": 0,
        "offeringsAvailable": 19,
        "sport": {
          "id": 26
        }
      },
      {
        "id": "3314",
        "composedId": "3314G",
        "name": "Tennis - Live",
        "lineType": "G",
        "part": 0,
        "offeringsAvailable": 1,
        "sport": {
          "id": 26
        }
      },
      {
        "id": "6250",
        "composedId": "6250G",
        "name": "NHL - Live",
        "lineType": "G",
        "part": 0,
        "offeringsAvailable": 4,
        "sport": {
          "id": 26
        }
      },
      {
        "id": "6250",
        "composedId": "6252P",
        "name": "NHL - Live (2P)",
        "lineType": "P",
        "part": 2,
        "offeringsAvailable": 2,
        "sport": {
          "id": 26
        }
      },
      {
        "id": "6250",
        "composedId": "6253P",
        "name": "NHL - Live (3P)",
        "lineType": "P",
        "part": 3,
        "offeringsAvailable": 2,
        "sport": {
          "id": 26
        }
      },
      {
        "id": "6711",
        "composedId": "6711G",
        "name": "NCAA Baseball - Live",
        "lineType": "G",
        "part": 0,
        "offeringsAvailable": 1,
        "sport": {
          "id": 26
        }
      }
    ],
    "img": "images/icons/icon_live_betting.svg"
  },
  {
    "id": 6,
    "name": "MLB",
    "priority": 1,
    "leagues": [
      {
        "id": "1496",
        "composedId": "1496G",
        "name": "MLB",
        "lineType": "G",
        "part": 0,
        "offeringsAvailable": 72,
        "sport": {
          "id": 6
        }
      },
      {
        "id": "1496",
        "composedId": "1497I",
        "name": "MLB (1I)",
        "lineType": "I",
        "part": 1,
        "offeringsAvailable": 30,
        "sport": {
          "id": 6
        }
      },
      {
        "id": "1496",
        "composedId": "1498I",
        "name": "MLB (2I)",
        "lineType": "I",
        "part": 2,
        "offeringsAvailable": 30,
        "sport": {
          "id": 6
        }
      },
      {
        "id": "1721",
          "id": 6
        }
      },
      {
        "id": "2012",
        "composedId": "2012T",
        "name": "MLB - Alternate Runlines",
        "lineType": "T",
        "part": 0,
        "offeringsAvailable": 30,
        "sport": {
          "id": 6
        }
      }
    ],
    "img": "images/icons/icon_mlb.svg"
  },
  {
    "id": 41,
    "name": "MLB  Props",
    "priority": 2,
    "leagues": [
      {
        "id": "6726",
        "composedId": "6726G",
        "name": "MLB Props - Runs+Hits+Error",
        "lineType": "G",
        "part": 0,
        "offeringsAvailable": 15,
        "sport": {
          "id": 41
        }
      },
      {
        "id": "6727",
        "composedId": "6727G",
        "name": "MLB Props - Team to score 1st",
        "lineType": "G",
        "part": 0,
        "offeringsAvailable": 15,
        "sport": {
          "id": 41
        }
      },
      {
        "id": "6728",
        "composedId": "6728G",
        "name": "MLB Props - 1st inning run?",
        "lineType": "G",
        "part": 0,
        "offeringsAvailable": 15,
        "sport": {
          "id": 41
        }
      },
      {
        "id": "6731",
        "composedId": "6731G",
        "name": "MLB Props - 1st Called pitch",
        "lineType": "G",
        "part": 0,
        "offeringsAvailable": 30,
        "sport": {
          "id": 41
        }
      },
      {
        "id": "6732",
        "composedId": "6732G",
        "name": "MLB Props - Players Matchups",
        "lineType": "G",
        "part": 0,
        "offeringsAvailable": 30,
        "sport": {
          "id": 41
        }
      },
      {
        "id": "6741",
        "composedId": "6741G",
        "name": "MLB Props - 1st inning line",
        "lineType": "G",
        "part": 0,
        "offeringsAvailable": 15,
        "sport": {
          "id": 41
        }
      }
    ],
    "img": "images/icons/icon_mlb.svg"
  },
  ... "composedId": "1721T",
        "name": "MLB - Grand Salami",
        "lineType": "T",
        "part": 0,
        "offeringsAvailable": 8,
        "sport": {
          "id": 6
        }
      },
      {
        "id": "2012",
        "composedId": "2012T",
        "name": "MLB - Alternate Runlines",
        "lineType": "T",
        "part": 0,
        "offeringsAvailable": 30,
        "sport": {
          "id": 6
        }
      }
    ],
    "img": "images/icons/icon_mlb.svg"
  },
  {
    "id": 41,
    "name": "MLB  Props",
    "priority": 2,
    "leagues": [
      {
        "id": "6726",
        "composedId": "6726G",
        "name": "MLB Props - Runs+Hits+Error",
        "lineType": "G",
        "part": 0,
        "offeringsAvailable": 15,
        "sport": {
          "id": 41
        }
      },
      {
        "id": "6727",
        "composedId": "6727G",
        "name": "MLB Props - Team to score 1st",
        "lineType": "G",
        "part": 0,
        "offeringsAvailable": 15,
        "sport": {
          "id": 41
        }
      },
      {
        "id": "6728",
        "composedId": "6728G",
        "name": "MLB Props - 1st inning run?",
        "lineType": "G",
        "part": 0,
        "offeringsAvailable": 15,
        "sport": {
          "id": 41
        }
      },
      {
        "id": "6731",
        "composedId": "6731G",
        "name": "MLB Props - 1st Called pitch",
        "lineType": "G",
        "part": 0,
        "offeringsAvailable": 30,
        "sport": {
          "id": 41
        }
      },
      {
        "id": "6732",
        "composedId": "6732G",
        "name": "MLB Props - Players Matchups",
        "lineType": "G",
        "part": 0,
        "offeringsAvailable": 30,
        "sport": {
          "id": 41
        }
      },
      {
        "id": "6741",
        "composedId": "6741G",
        "name": "MLB Props - 1st inning line",
        "lineType": "G",
        "part": 0,
        "offeringsAvailable": 15,
        "sport": {
          "id": 41
        }
      }
    ],
    "img": "images/icons/icon_mlb.svg"
  },
  ...

我正在使用 LODASH 迭代数组。但是我不知道如何完成这个任务

编辑

不要因为我上面提到的现场投注而感到困惑,我的意思是,我希望阵列中的每项运动都发生同样的情况。

尝试:

// in view, replace
{{sport.leagues.length}}

// with
{{ total(sport) }}

//in controller, add scope method
$scope.total = function(sport) {
    return _.sum(_.pluck(sport.leagues, 'offeringsAvailable'));
}

建议在收到数据时循环遍历每项运动并添加一个包含总和

offerings 属性
sports.forEach(function(sport){ 
    sport.offerings=sport.leagues.reduce(function(prev,curr){     
        return prev + (curr.offeringsAvailable||0);
    },0);
});

然后在header中使用{{sport.offerings}}