首页 > 解决方案 > 角度:将可观察数组转换为数组以使用数据

问题描述

我正在尝试从我的数据服务中获取数据以在 openstreetmap 上显示为精确点。

当我使用静态数据对 1 个精确点进行尝试时,它可以工作并且精确点显示。现在我想使用我的数据服务来获取一个停车对象数组,并在我的地图中使用它们来创建这些精确点。但是,我没有显示精确点,当我在我的地图组件中从循环中记录停车时,它只显示第一个,当我在控制台中记录它时,数组显示为未定义。

问题是我试图从数据服务中调用一个方法,该方法返回一个可观察的停车对象数组。现在我想循环遍历可观察数组以获取每个单独的停车对象,我想从中提取其经度和纬度以使其显示在地图上

我是 Angular 的新手,所以我认为这可能与我收到的可观察数组有关,但不知道如何将其转换为普通数组,我尝试添加 .subscribe 没有任何运气

代码图

  map;
  testp;
  vectorSource;
  vectorLayer;
  rasterLayer;
  features: Feature[];
  constructor(
    private _pds: ParkingDataService
  ) { }

  ngOnInit(): void {
    this.createParkPoints();
    this.vectorSource = new VectorSource({
      features: this.features
    });

    this.vectorLayer = new VectorLayer({
      source: this.vectorSource
    });
    this.initializeMap();

  }

  createParkPoints(){
    this._pds.allParkings$.forEach( (parkings: Parking[]) =>{
      parkings.forEach((parking: Parking) => {
        console.log(parking);
        let ftre: Feature = new Feature({
          geometry: new Point(fromLonLat([parseFloat(parking.longtitude), parseFloat(parking.latitude)]))
        });

        ftre.setStyle(new Style({
          image: new Icon(({
            color: '#8959A8',
            crossOrigin: 'anonymous',
            src: 'assets/park.svg',
            imgSize: [30, 30]`enter code here`
          }))
        }));

        this.features.push(ftre);
      })
    })
  }

  initializeMap(){
    this.map = new Map({
      target: 'map',
      layers: [ new TileLayer({
        source: new OSM()
      }), this.vectorLayer ],
      view: new View({
        center: fromLonLat([3.7219431, 51.054633]),
        zoom: 15,
      })
    });
  }

}

代码数据服务

export class ParkingDataService {
  private _parkings$ = new BehaviorSubject<Parking[]>([]);
  private _parkings: Parking [];

  constructor(private http: HttpClient) {
    this._parkings$
    .pipe(
      catchError(err => {
        this._parkings$.error(err);
        return throwError(err);
      })
    )
    .subscribe((parkings: Parking[]) => {
      this._parkings = parkings;
      this._parkings$.next(this._parkings);
    });
   }

  get allParkings$(): Observable<Parking[]>{
    return this.parkings$;
  }

  get parkings$(): Observable<Parking[]>{
    return this.http.get(`${environment.apiUrl}/Parking`).pipe(
      tap(console.log),
      shareReplay(1),
      catchError(this.handleError),
      map((list: any[]): Parking[] => list.map(Parking.fromJSON))
    );

  }

  get parkings(){
    this.parkings$.subscribe(parkings =>{
      this._parkings = parkings as Parking[];
    });
    console.log(this._parkings);
    return this._parkings;
  }

  getParking$(id: number): Observable<Parking>{
    return this.http
      .get(`${environment.apiUrl}/Parking/${id}`)
      .pipe(catchError(this.handleError), map(Parking.fromJSON));
  }

  handleError(err: any): Observable<never> {
    let errorMessage: string;
    if (err.error instanceof ErrorEvent) {
      errorMessage = `An error occurred: ${err.error.message}`;
    } else if (err instanceof HttpErrorResponse) {
      console.log(err);
      errorMessage = `'${err.status} ${err.statusText}' when accessing '${err.url}'`;
    } else {
      errorMessage = err;
    }
    return throwError(errorMessage);
  }
}

标签: angulartypescriptopenlayersopenstreetmap

解决方案


该服务正在返回一个可观察的类型Parking[](停车场数组)

所以,为了得到这些停车位,我们需要在组件中订阅那个 observable

在服务中我们只需要返回可观察对象,然后在组件中订阅它

我们需要服务中的一个简单函数来从服务器加载所有停车位,而不需要您在服务中使用的所有 getter

所以我们可以在服务中使用这样的功能

在这个函数中,我们将返回 observable

loadAllParkings() {
    // here we will call the HTTP Request which returns an observable
    // you can omit this <Parking[]>, this refers to the return type of this http request, you can define this type in the map operator as you did before

    return this.http.get<Parking[]>(`${environment.apiUrl}/Parking`).pipe( // we are returning the observable here, so in the component we subscribe to this observable
        // do all the rxjs operators you need here
        // tap, map, catchError, ... and so on, as you need
    );
}

现在我们有了一个类型为 Parkings 数组的 observable,所以在组件中,我们只需要订阅那个 observable

在组件中

createParkPoints () {
    // the function loadAllParkings in the service returns an observable, so we can do the subscription here
    this._pds.loadAllParkings().subscribe((parkings: Parking[]) => {
        // now you have the parkings array, loop over it
    });
}

推荐阅读