如何在Angular中订阅Observable

时间:2019-08-07 14:16:13

标签: angular typescript

我正在尝试订阅一个Observable,因此我可以使用Angular在HTML中显示它,console.log(player)可以正常工作,但是我得到

Type 'Player' is missing the following properties from type 'Observable<Player>': _isScalar, source, operator, lift, and 6 more.ts(2740)

我尝试使用.pipe()

HTML:

<div *ngIf="(player$ | async) as player">
  <div *ngIf="player.characterUid">
    {{player.characterName}}
  </div>
</div>

组件:

player$: Observable<Player>;
subPlayer: Subscription;

selectPlayer(matEvent: MatAutocompleteSelectedEvent): void {
    this.inputFriends = matEvent.option.value;
    this.selectedPlayer = matEvent.option.value;
    this.inputP = false;

    this.subPlayer = this.playerProvider.get$(matEvent.option.value.userUid).subscribe(
      (player: Player) => {
        this.player$ = player; // Type 'Player' is missing the following properties from type 'Observable<Player>': _isScalar, source, operator, lift, and 6 more.ts(2740)
      }
    );
  }

提供者:

get$(uid: string): Observable<Player> {
    return this._getDoc(uid)
      .valueChanges()
      .pipe(
        map((sPlayer: ServerPlayer) => sPlayer ? new Player(sPlayer) : null)
      );
  }

  private _getDoc(uid: string): AngularFirestoreDocument {
    return this.afs.doc(`players/${uid}`);
  }

我只是尝试分配player$,以便可以在HTML中显示

3 个答案:

答案 0 :(得分:1)

在您的代码player$中不是可观察的,它已经是可观察的结果。

player: Player; // <-- here
subPlayer: Subscription;

selectPlayer(matEvent: MatAutocompleteSelectedEvent): void {
    this.inputFriends = matEvent.option.value;
    this.selectedPlayer = matEvent.option.value;
    this.inputP = false;

    this.subPlayer = this.playerProvider.get$(matEvent.option.value.userUid).subscribe(
      (player: Player) => {
        this.player = player; // <-- here
      }
    );
  }
<div *ngIf="player"> <!-- here -->
  <div *ngIf="player.characterUid">
    {{player.characterName}}
  </div>
</div>

答案 1 :(得分:1)

您不需要订阅,异步管道将订阅并为您获取值?‍♂️

player$: Observable<Player>;

selectPlayer(matEvent: MatAutocompleteSelectedEvent): void {
    this.inputFriends = matEvent.option.value;
    this.selectedPlayer = matEvent.option.value;
    this.inputP = false;

    this.player$= this.playerProvider.get$(matEvent.option.value.userUid);

  }
  

异步管道负责按以下方式订阅和解包数据:   以及取消销毁组件时的订阅,因此您不需要 subPlayer

模板

<ng-container *ngIf="(player$ | async) as player">
  <div *ngIf="player.characterUid">
    {{player.characterName}}
  </div>
</ng-container>

Async Pipe ?

答案 2 :(得分:1)

  

我只是想分配玩家$,以便可以将其显示在HTML中

this.player$ = this.playerProvider.get$(matEvent.option.value.userUid);

此方法返回一个可观察的值,因此,如果要分配player$,可以这样做。在您的html模板中,您使用的是| async,它可以自动处理订阅/退订。