Angular - 编辑一个 BehaviorSubject 数组

Angular - edit a BehaviorSubject Array

我正在向服务器发送请求以修改其中一位用户。

作为响应,服务器发回更新后的用户。

之后我尝试像这样更新所有用户的 BehaviorSubject:

   private currentHeroes = new BehaviorSubject<Hero[]>(null);
   currentHeroes$ = this.currentHeroes.asObservable();


 powerUp(id: number) {
return this.http
  .post<Hero>(environment.apiUrl + 'heroes/powerUp/' + id, {})
  .pipe(
    tap((updatedHero: Hero) => {
      this.currentHeroes.next(
        this.currentHeroes.value.map((hero: Hero) =>
          hero.id === updatedHero.id ? updatedHero : hero
        ).sort(a=>a.currentPower)
      );
    })
  );

}

如果删除:

    delete(id: number) {
return this.http.delete<Hero>(environment.apiUrl + 'heroes/' + id).pipe(
  tap((deletedHero: Hero) => {
    this.currentHeroes.value.filter(
      (hero: Hero) => hero.id !== deletedHero.id
    );
  })
);

}

我正在尝试修改用户数组。用更新的用户替换旧用户。

并且代码没有到达 currentHeroes$ 的管道。 我不太确定为什么会这样或者我该如何解决它。

我曾尝试 return 来自管道的值或使用 tap 而不是 map 但没有成功。

有没有人可以看看并向我解释为什么会这样?或者我该如何解决?

谢谢!

正在更新数组中的对象

变体 1:使用 value getter 的 BehaviorSubject

您不必 pipeBehaviorSubject。您只需要在源可观察对象(HTTP 请求)上使用 tap 运算符并在其回调中更新 BehaviorSubjecttap 运算符类似于 map 但不会转换传入的排放量。所以它非常适合执行更新局部变量等副作用。

import { tap } from 'rxjs/operators';

powerUp(id: number) {
  return this.http.post<Hero>(environment.apiUrl + 'heroes/powerUp/' + id, {}).pipe(
    tap((updatedHero: any) => {
        this.currentHeroes.next(
          this.currenHeroes.value.map((hero: Hero) =>        // <-- `Array#map` function
            hero.id === updatedHero.id ? updatedHero : hero
          )
        );
      }
    })
  );
}

变体 2:使用 withLatestFrom 运算符

如果您不想使用 value getter from the BehaviorSubject, you could try to use the withLatestFrom 运算符来获取它的最新值。

import { tap, withLatestFrom } from 'rxjs/operators';

powerUp(id: number) {
  return this.http.post<Hero>(environment.apiUrl + 'heroes/powerUp/' + id, {}).pipe(
    withLatestFrom(this.currentHeroes$),
    tap(([updatedHero, currentHeroes]) => {
        this.currentHeroes.next(
          currenHeroes.map((hero: Hero) => 
            hero.id === updatedHero.id ? updatedHero : hero
          )
        );
      }
    })
  );
}

正在删除数组中的一个对象

如评论中所述,要删除数组中的元素,您可以使用 Array#filter 而不是 Array#map 函数。

变体 1:使用 value getter 的 BehaviorSubject

import { tap, withLatestFrom } from 'rxjs/operators';

powerUp(id: number) {
  return this.http.delete<Hero>(environment.apiUrl + 'heroes/' + id).pipe(
    tap(([deletedHero, currentHeroes]) => {
        this.currentHeroes.next(
          this.currentHeroes.value.filter((hero: Hero) => hero.id !== deletedHero.id)
        );
      }
    })
  );
}

变体 2:使用 withLatestFrom 运算符

import { tap, withLatestFrom } from 'rxjs/operators';

powerUp(id: number) {
  return this.http.delete<Hero>(environment.apiUrl + 'heroes/' + id).pipe(
    withLatestFrom(this.currentHeroes$),
    tap(([deletedHero, currentHeroes]) => {
        this.currentHeroes.next(
          currentHeroes.filter((hero: Hero) => hero.id !== deletedHero.id)
        );
      }
    })
  );
}