首页 > 解决方案 > Angular 9 <- 如何订阅 Observable 并显示其值

问题描述

亲爱的,

我被卡住了,我遵循了 http.get 和 observables 的简单 angular.io 教程,但我无法在视图中呈现数据。

我的服务:

import { Injectable } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { Observable } from "rxjs";
import { map } from "rxjs/operators";

const baseUrl = "http://localhost:4000";
const fetchAllHeroesUrl = "/heroes";
@Injectable({
  providedIn: "root",
})
export class HeroesService {
  constructor(private http: HttpClient) {}
  getHeroes(): Observable<any> {
    return this.http.get(baseUrl + fetchAllHeroesUrl);
  }
}

我的组件:

import { Component, OnInit } from "@angular/core";
import { HeroesService } from "./../shared/services/heroes.service";
import { Observable } from "rxjs";
@Component({
  selector: "app-hero-list",
  templateUrl: "./hero-list.component.html",
  styleUrls: ["./hero-list.component.scss"],
})
export class HeroListComponent implements OnInit {
  public listOfHeroes$: any;
  constructor(private heroesService: HeroesService) {}

   ngOnInit() {
     this.getAllHeroes();
  }
  getAllHeroes(): void {
   this.heroesService
      .getHeroes().subscribe((value: any) =>  this.listOfHeroes$ = value.data);
  }
}

我的模板:

<mat-list>
    <mat-list-item *ngFor="let hero of listOfHeroes$ | async">
        <img
            matListAvatar
            src="hero.avatar_url"
            alt="hero.full_name">
        <h3 matLine>{{hero.full_name}}</h3>
        <p matLine>
            <span>{{hero.description}}</span>
            <span class="demo-2">-- {{hero.type}}</span>
        </p>
    </mat-list-item>
</mat-list>

但是视图中仍然没有显示任何内容(在网络浏览器中,我还检查了开发工具中的网络选项卡,并且数据来自我的本地服务器),每当我 console.log(this.listOfHeroes$) 我得到未定义的时候不应该这样工作吗?我错过了什么吗?

标签: angulartypescriptrxjsobservable

解决方案


您既在控制器中订阅又在使用async管道。它应该是两者之一。两者都有它的优点和缺点。在这种情况下,我建议您执行以下操作

完全删除getAllHeroes()功能并修改控制器

export class HeroListComponent implements OnInit {
  public listOfHeroes$: any;
  constructor(private heroesService: HeroesService) {}

   ngOnInit() {
     this.listOfHeroes$ = this.heroesService.getHeroes();
  }
}

并且在模板中

<ng-container *ngIf="listOfHeroes$ | async as list">
  <mat-list-item *ngFor="let hero of list?.data">
    <img
      matListAvatar
      src="hero.avatar_url"
      alt="hero.full_name">
    <h3 matLine>{{hero.full_name}}</h3>
    <p matLine>
      <span>{{hero.description}}</span>
      <span class="demo-2">-- {{hero.type}}</span>
    </p>
  </mat-list-item>
<ng-container>

我更喜欢这里的一个原因async是因为它负责取消订阅 HTTP GET 以避免潜在的内存泄漏问题。


推荐阅读