如何使用 RxJS 将两个 Subjects/Action 流作为 GET 请求中的 HTTP 参数传递给 return Angular 中的单个 object/Array 对象?

How to pass two Subjects/Action streams as HTTP Params in a GET request to return a single object/Array of objects in Angular using RxJS?

OBJECTIVE: 我想 GET 单个对象 and/or 我后端的一系列对象通过使用 RxJS 将用户输入作为 HTTP 参数传递来提供服务。 例如,我正在使用声明式 RxJS,因此我有两个主题(操作流)来在用户点击提交时获取用户的输入。我想将这些主题值 作为 HTTP 参数 传递到我的 http 请求中,以便获取指定的 bay 对象或一系列 bay。 第一个 Subject/UserInput 将始终是强制性的,而第二个 Subject/UserInput 将是可选的。因此,如果有人在第一次输入时输入 4,然后在第二次输入时什么也不输入。后端将接受 4 和 'null' 这两个输入,因为没有输入任何内容。如果是这种情况,return 间隔号为 4 的间隔。如果有第二个输入,如 6,return 从 4 -> 6 的一系列间隔,如果它们存在的话。

问题:如何使用声明式 RxJS 将这两个主题作为 http 参数传递?

这是我的两个主题及其方法,以及我在 bay-service.ts 文件中对 HTTP 请求的尝试。

  private bayStartSelectedSubject = new Subject<number>();
  baySelectedAction$ = this.bayStartSelectedSubject.asObservable();

  private bayEndSelectedSubject = new Subject<number>();
  bayEndSelectedAction$ = this.bayEndSelectedSubject.asObservable();

  selectedBayChanged(selectedBayStartNumber: number, selectedBayEndNumber?: number): void {
    this.bayStartSelectedSubject.next(selectedBayStartNumber);
    this.bayEndSelectedSubject.next(selectedBayEndNumber);
  }

  private HandlingUnitResponseUrlSecondary = 'http://localhost:8080/sbtemplate/readBayInventory';


bayOrBays$ = combineLatest([
    this.baySelectedAction$,
    this.bayEndSelectedAction$
  ])
    .pipe(
      map(([bayStart, bayEnd]) => {
        mergeMap(() => this.http.get<HuResponse>(`${this.HandlingUnitResponseUrlSecondary}/COS/${bayStart}/${bayEnd}`))
      })
    );

这里是我在我的 bay-page.ts 文件中获取用户输入的地方,并调用他们的方法来发出用户输入值:

onSubmit() {
    this.bayService.selectedBayChanged(this.bayForm.get('bayStart').value, this.bayForm.get('bayEnd').value);
    if(!this.invalidBay) {
      this.bayDoesNotExistError = true;
      this.selectedBay = this.bayForm.get('bayStart').value;
      this.vibration.vibrate(500);
      console.log('Vibrating for 3 second...')
    } else {
      this.navCtrl.navigateForward([`/results/`]);
    }

我知道代码看起来不太好,但我找不到这方面的任何信息。感谢您的帮助!

还有 这是我要访问的后端 API:

@RequestMapping(value="/readBayInventory/{centerId}/{beginBayId}/{endBayId}", method = GET)
    public ResponseEntity<HUResponse> readBayInventory(@PathVariable String centerId, @PathVariable int beginBayId, @PathVariable(required = false) int endBayId) {

您可以尝试改变您声明的方式bayOrBays并移动到这种形式

const bayOrBays$ = combineLatest([
  baySelectedAction$,
  bayEndSelectedAction$
]).pipe(
  concatMap(([bayStart, bayEnd]) => this.http.get<HuResponse>(`${this.HandlingUnitResponseUrlSecondary}/COS/${bayStart}/${bayEnd}`))
);

这段代码基本上意味着每当 2 个主题之一发出新值时,您将触发 http 调用和 return 它的结果。 concatMap 是所谓的“高级运算符”之一,即是一个运算符,它接受一个函数,该函数 returns 一个 Observable 和 returns 这种 Observable 发出的值(在其他说它“扁平化”了内部 Observable return 由作为输入传入的函数编辑)。

其他“高级运算符”是 mergeMap(又名 flatMap)、switchMapexahustMap。它们的行为略有不同,但对于 http 调用,通常 concatMap 是一个安全的默认值。您可能会从 this article.

获得一些关于如何在与 http 相关的常见用例中使用 rxJs 的灵感

最后,目前你得到 Observable<void> 作为 bayOrBays$ 类型的部分原因是你传递给 mergeMap 的函数不是 return 任何事物。请记住,如果您使用大括号来定义函数的主体,则必须显式使用 return 语句来 return 某些内容。相反,如果您对正文使用单行格式(即没有花括号),则函数 returns 无论执行该行的结果是什么。

因此,这种格式(您使用的格式)没有 return 任何东西

const myFunction = () => {
  doStuff();
}

虽然这两种格式 return 无论如何 doStuff() returns

const myFunction = () => {
  return doStuff();
}

const myFunction = () => doStuff()