如何将新项添加到Array类型的Observable上?

问题描述

我正在研究英雄的环游示例。有一项功能可以将新英雄添加到现有英雄列表中。 我在hero.service.ts中添加英雄的方法如下:

addNewHero(hero : Hero) : Observable<Hero> {
    console.log(hero)
   return this._http.post<Hero>(this.url,hero).pipe(
    tap(res => this._service.addMessage(`new hero is ${hero.name} added`)),catchError(error => this.handleerror('adding a hero'))

   )
  }
Heroescomponent类中的

addHero方法如下:

export class HeroesComponent implements OnInit {

  heroes : Observable<Array<Hero>>;
  selectedHero: Hero;

  constructor(private _service : HeroService,private _router : Router) { }

  ngOnInit() {
    this.heroes = this._service.getHeroes()
  }

  onSelect(hero: Hero): void {
    this.selectedHero = hero;
  }

  details(id : Number) {
    this._router.navigate(['heroes',id])
  }

  **addHero(name : String){
    console.log(name)
    this._service.addNewHero({ name } as Hero).subscribe((res : Hero) => {
      this.heroes = this._service.getHeroes()
     
    })
  }**
}

Heroes.HTML文件如下:

<h2>My Heroes</h2>
<div>
  <input type="text" #heroname>
  <button (click) = "addHero(heroname.value)">Add</button>
</div>
<ul class="heroes">
  <li *ngFor="let hero of heroes | async">
    <a routerLink = "/detail/{{hero.id}}"
    style = "text-decoration : none"><span class="badge">{{hero.id}}</span> {{hero.name}}</a> 
  </li>
</ul>

我正在使用heroes类型的Observable<Hero[]>变量。

因此,每当我添加新英雄时,我都想向现有heroes添加添加的英雄。但是,我无法执行此操作,因为observable of arrays没有推送方法。因此,我再次调用getHeroes方法刷新列表显示添加的项目。是否有任何解决方法可将项目添加到数据类型Observable<Array>中,而不是再次击中服务器

解决方法

您可以使用Subject,如下所示:

export class HeroesComponent implements OnInit {

    heroes = new Subject<Array<Hero>>();
    heroes$ = this.heroes.asObservable();
    selectedHero: Hero;
  
    constructor(private _service : HeroService,private _router : Router) { }
  
    ngOnInit() {
      this._service.getHeroes().subscribe(heroes => this.heroes.next(heroes))
    }
  
    onSelect(hero: Hero): void {
      this.selectedHero = hero;
    }
  
    details(id : Number) {
      this._router.navigate(['heroes',id])
    }
  
    addHero(name : String){
      
      this._service.addNewHero({ name } as Hero).pipe(
          withLatestFrom(this.heroes)
      ).subscribe(([newHero,currentHeroes]) => {
        this.heroes.next(currentHeroes.concat(newHero))
       
      })
    }
  }

主题提供了next方法,该方法允许您发出一个新值,该值将成为heroes$可观察的值,因为heroes主题是其来源。