如何从Angular 2/4中的Promise <array []>中选择唯一元素?

时间:2017-06-14 16:38:39

标签: javascript angular

很少有上下文,我有一个API,可以返回一个带有匹配链接的比赛,每个比赛都有一个链接到比赛的球队。

我现在的目的是根据比赛比赛建立一个排名表,我的第一步是打印一系列独特的“球队”列表。那就是我需要经历所有比赛,检查主队和客队,如果球队不在场,请将其推入列表。

这是棘手的部分,我有这样的团队:

match.away = this.teamService.getTeam(match._links.awayTeam.href);
match.home = this.teamService.getTeam(match._links.homeTeam.href);

我的getTeam()方法返回一个承诺团队

getTeam(id: string): Promise<Team> {
    return this.http.get(id)
           .toPromise()
           .then(response => response.json() as Team)
           .catch(this.handleError);
   }

团队类有 teamName:string; ,这是我需要验证以构建数组的值,这是我需要帮助的部分。我有一个OnInit实现,如下所示:

ngOnInit(): void {
      this.teams = [];
      this.route.params
        .switchMap((params: Params) => this.competitionService.getCompetition(+params['id']))
    .subscribe(competition => {
      this.competitionService.getMatches(competition)
        .then(
          matches => {
            matches.forEach(match => {
              match.away = this.teamService.getTeam(match._links.awayTeam.href);
              match.home = this.teamService.getTeam(match._links.homeTeam.href);
              match.away.then(away => {
                var found = this.teams.find(team => {
                  return team.teamName.toLocaleLowerCase().includes(away.teamName)
                });
                if(!found) {
                  this.teams.push(away);
                }
              });
              match.home.then(home => {
                var found = this.teams.find(team => {
                  return team.teamName.toLocaleLowerCase().includes(home.teamName)
                });
                if(!found) {
                  this.teams.push(home);
                }
              });
            });
            return matches;
          }
        ).then(matches => 
          this.matches = matches
        );
      this.competition = competition
  });
}

我尝试做的是首先解决Promise并检查团队在我的阵列中的存在,如果是,找到了,然后将其推送到列表中。

我的HTML看起来像这样:

<md-list>
    <md-list-item *ngFor="let team of teams">
        <button md-raised-button>{{team.teamName}}</button>
    </md-list-item>
</md-list>

但结果是每个匹配中每个团队的列表,所以推送部分显然正在运行,因为数组团队:Team []; 正在填充,打印正确,但验证不是。

请不要因为我的代码而杀了我,因为我对此有所了解,我只是在飞行中学习,不仅仅是Angular而是代码。

所以我的问题是:

如何根据比赛承诺建立一系列独特的球队?

此外,您通常如何为这些计算拆分数组?我发现的每项研究都指向一个“自定义管道”但它似乎只是过滤了视图,在我拥有我的阵列之后,我必须对目标的每个匹配进行计算,点等等,所以它似乎不适合我。

有任何想法或建议吗?

1 个答案:

答案 0 :(得分:0)

我将添加一个新方法来委派teams数组:

addToSet(team): void {
    let teamNames: string[] = this.teams.map((team) => team.teamName.toLocaleLowerCase());

    if (teamNames.lastIndexOf(team.teamName.toLocaleLowerCase()) === -1) {
       this.teams.push(team);
    }
}

然后,替换这部分

var found = this.teams.find(team => {
    return team.teamName.toLocaleLowerCase().includes(home.teamName)
});
if(!found) {
    this.teams.push(home);
}

this.addToSet(home);

此外,为了确保在继续加载数组之前完成两个promise,您可以使用getTeam打包Promise.all个调用。

Promise.all([
   this.teamService.getTeam(match._links.awayTeam.href),
   this.teamService.getTeam(match._links.homeTeam.href)
]).then((teams) => {
   match.away = teams[0];
   match.home = teams[1];
});

编辑:把它们放在一起

addToSet(team): void {
    let teamNames: string[] = this.teams.map((team) => team.teamName.toLocaleLowerCase());

    if (teamNames.lastIndexOf(team.teamName.toLocaleLowerCase()) === -1) {
       this.teams.push(team);
    }
}

ngOnInit() {
     // rest of the initialization
     matches.forEach(match => {
         Promise.all([
             this.teamService.getTeam(match._links.awayTeam.href),
             this.teamService.getTeam(match._links.homeTeam.href)
         ]).then(teams => {
             match.away = teams[0];
             match.home = teams[1];

             this.addToSet(away);
             this.addToSet(home);
         });
     });
 }

编辑2:在toLocaleLowerCase()中添加addToSet()进行检查。我假设getTeam返回单个对象,否则,您需要强制执行返回的对象架构。