You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 14:如何在pipe中通过map筛选控球后卫子数组

问题背景

我正在重构一个Web应用,该应用展示金州勇士队的球员阵容,点击球员图片可查看NBA球员的更详细信息。
我通过Observable(roster-data.service.ts)和.subscribe()(players.component.ts)从JSON Server/JSON Placeholder获取数据,基于为每位球员创建的Player类(player.ts)进行开发,该类通过名为enumPosition.ts的枚举将球员分为五个位置,每个位置对应一个数字。

枚举定义(enumPosition.ts)

export enum Position {
    PointGuard = 1,
    ShootingGuard = 2,
    SmallForward = 3,
    PowerForward = 4,
    Center = 5,
}

Player类(player.ts)

import { Position } from "../models/enumPosition";

export class Player {

  constructor(
    public fullName: string,
    public shirtNumber: string,
    public position: number,
    public height: string,
    public weight: number,
    public points: number,
    public rebounds: number,
    public assists: number,
    public blocks: number,
    public steals: number,
    public imageFile: string,
    public imageDescrip: string
  ) {
    this.fullName = fullName;
    this.shirtNumber = shirtNumber;
    this.position = position;
    this.height = height;
    this.weight = weight;
    this.points = points;
    this.rebounds = rebounds;
    this.assists = assists;
    this.blocks = blocks;
    this.steals = steals;
    this.imageFile = imageFile;
    this.imageDescrip = imageDescrip;
  }
}

组件控制器(players.component.ts)

import { Component, OnInit, isDevMode } from '@angular/core';
import { RosterDataService } from "../../services/roster-data.service";
import { Player } from "../../models/player";
import { imgRoute } from "../../services/img-route.service";

@Component({
  selector: 'app-players',
  templateUrl: './players.component.html',
  styleUrls: ['./players.component.scss'],
  providers: [RosterDataService]
})
export class PlayersComponent implements OnInit {
  public imageLocation:string;
  public pointGuards!: Player[];
  public shootingGuards!: Player[];
  public smallForwards!: Player[];
  public powerForwards!: Player[];
  public centers!: Player[];
  public getPlayers: Player[] = [];


  constructor(private _rosterDataService: RosterDataService) {
    this.imageLocation = imgRoute.path;
  }

  ngOnInit(): void {
    this.dev_SuscribeAllPointGuards();
  }

  dev_SuscribeAllPointGuards(){
    this._rosterDataService.jSON_Server_ReadPointGuards().subscribe(
      pointguards => {
        this.pointGuards = pointguards;
      }  
    );
  }
}

服务文件(roster-data.service.ts)

import { Injectable } from '@angular/core';
import { Player } from "../models/player";
import { environment } from "../../environments/environment";
import {HttpClient, HttpErrorResponse} from '@angular/common/http';
import {Observable, throwError} from 'rxjs';
import {catchError, map, filter} from 'rxjs/operators';
import { Position } from '../models/enumPosition';

@Injectable({
  providedIn: 'root'
})
export class RosterDataService {

  private readonly devURL = environment.url;

  public bases!: Player[];
  public escoltas!: Player[];
  public aleros!: Player[];
  public alaPivots!: Player[];
  public pivots!: Player[];
  public players!: Player[];
  
  constructor(private http: HttpClient) {
  }

  jSON_Server_ReadPointGuards():Observable<Player[]> {
    return this.http.get<Player[]>(this.devURL + "/roster_GoldenStateWarriors").pipe(
      map((jugones:Player[]) => { jugones.find(player => player.position === 1); return jugones;}),
      catchError(this.handleError)
    );
  }

  private handleError(err: HttpErrorResponse) {

      let errorMessage = '';
      if (err.error instanceof ErrorEvent) {

          errorMessage = `An error occurred: ${err.error.message}`;
      } else {

          errorMessage = `Server returned code: ${err.status}, error message is: ${err.message}`;
      }
      console.error(errorMessage);
      return throwError(() => errorMessage);
  }

}

问题

如何正确筛选出仅包含控球后卫(player.position == 1)的子数组?

解决方案

你当前代码的问题在于使用了Array.find()方法,该方法仅返回数组中第一个符合条件的元素,而非所有符合条件的元素集合。要筛选出所有控球后卫,需要替换为Array.filter()方法,该方法会返回所有满足条件的元素组成的新数组。

1. 修改现有方法

更新roster-data.service.ts中的jSON_Server_ReadPointGuards()方法:

jSON_Server_ReadPointGuards():Observable<Player[]> {
  return this.http.get<Player[]>(this.devURL + "/roster_GoldenStateWarriors").pipe(
    // 使用filter替换find,并直接引用枚举值增强可读性
    map((jugones: Player[]) => jugones.filter(player => player.position === Position.PointGuard)),
    catchError(this.handleError)
  );
}

这里直接使用枚举值Position.PointGuard而非硬编码数字1,能提升代码的可维护性——如果后续枚举值有修改,无需逐个修改硬编码的数字。

2. 通用位置筛选方法(推荐)

为避免重复编写多个类似的位置筛选方法,可以封装一个通用函数,支持传入任意位置枚举值获取对应球员:

// 在RosterDataService类中添加该方法
getPlayersByPosition(position: Position): Observable<Player[]> {
  return this.http.get<Player[]>(this.devURL + "/roster_GoldenStateWarriors").pipe(
    map(players => players.filter(player => player.position === position)),
    catchError(this.handleError)
  );
}

之后在组件中调用时,只需传入对应枚举值即可:

// 在players.component.ts的dev_SuscribeAllPointGuards方法中修改
dev_SuscribeAllPointGuards(){
  this._rosterDataService.getPlayersByPosition(Position.PointGuard).subscribe(
    pointguards => {
      this.pointGuards = pointguards;
    }  
  );
}
// 同理,获取其他位置球员也可以直接调用
// this._rosterDataService.getPlayersByPosition(Position.Center).subscribe(...);

内容的提问来源于stack exchange,提问作者Eric Díaz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 14:20:50