在打字稿文件中使用 .subscribe 之外的数据

use data outside of .subscribe in typescript file

我是 typescript/ionic 4 的新手。我正在尝试访问存储在 firebase 中的数据并在我的打字稿文件中使用它。在 .subscribe 中时,我可以按要求显示数据。但这不是我要找的。我需要在我的 page.ts .

上执行 .subscribe 之外的计算

我见过很多类似的问题,但我似乎找不到解决方案。

这是我的 Typescript 服务文件

  export interface Place{
    title: string;
    type: string;
    latitude: number;
    longitude: number;
 }
 export class PlaceService {
 placess: Place[];
 place: Place;
 private placesCollection: AngularFirestoreCollection<Place>;
 private places: Observable<Place[]>;

 constructor(db: AngularFirestore) {
    this.placesCollection = db.collection<Place>('places');

    this.places = this.placesCollection.snapshotChanges().pipe(
    map(actions =>{
      return actions.map(a => {
        const data = a.payload.doc.data();
        const id = a.payload.doc.id;
        return{ id, ...data};
      });
    })
  );
 }
 getPlaces() {
    return this.places;
 }
 }

以及我页面中的相关部分typescript

import { PlaceService, Place } from '../services/place.service';

places: Place[];
ngOnInit() {
this.placeService.getPlaces()
  .subscribe(res =>{
  this.places = res;
  console.log(this.places[0].title);//WORKS
});

console.log(this.places[0].title);//FAILED
 }

我收到以下错误消息:

 MapPage_Host.ngfactory.js? [sm]:1 ERROR TypeError: Cannot read property '0' of undefined

.subscribe 方法必须完成(ajax 请求必须是 200-OK),在 subscribe 方法中你可以存储到你的局部变量中,然后进一步修改是可能的。

您不能使用没有数据的变量。

this.placeService.getPlaces()
  .subscribe(res =>{
  this.places = res;  
});

将需要几秒钟来完成 ajax 调用并获取响应并存储在 "Places" 中。

解决方法(不推荐)使用 set timeout function 等待至少 2 秒。增加秒数,直到找到完成请求和响应的最短秒数。

然后你可以对this.places做一些计算。

您的问题是您的代码按照您编写的方式运行。当页面初始化时,调用 ngOnInit。在代码内部转到第一个元素 (this.placeService.getPlaces() ... ) 并立即转到第二个元素 (console.log(this.places[0])。这会引发错误,因为places 变量尚未在您调用 placeService 时设置,目前为 undefined.

ngOnInit() {
  this.placeService.getPlaces() // called first
    .subscribe(res =>{
    this.places = res;
    console.log(this.places[0].title);
});

console.log(this.places[0].title); // called second (undefined error)
}

如果您在设置 places 变量后调用一个函数,第二个 console.log() 将起作用。

ngOnInit() {
  this.placeService.getPlaces()
    .subscribe(res =>{
    this.places = res;
    console.log(this.places[0].title);
    this.showFirstTitle(); // this.places is set
  });
}

showFirstTitle() {
  console.log(this.places[0].title); // will work
}