将asObservable()与Angular中的Subject一起使用时,未触发Observable吗?

时间:2019-06-30 18:25:35

标签: angular observable

我有一个向用户显示表单的组件。用户选择该表单上的“提交”按钮后,我想触发向后端发送http.post请求

我想使用BehaviorSubject和.asObservable()一起使用|异步管道来实现这一目标。

我在PreOrderComponenT组件ts文件中进行了以下设置:

preOrder$ = this.preOrderService.preOrder$;

onSubmit() {
    console.log(this.preOrderForm);
    const preOrderForm: PreOrderForm = {
      firstName: this.preOrderForm.value.firstName,
      lastName: this.preOrderForm.value.lastName,
      phoneNumber: this.preOrderForm.value.phoneNumber,
      email: this.preOrderForm.value.email,
      orderDetails: {
        quantity: this.preOrderForm.value.orderDetails.quantity,
        size: this.preOrderForm.value.orderDetails.size,
        gearItemId: this.gearItem.id
      },
      contactPreference: {
        cellOrEmail: this.preOrderForm.value.contactPreference.cellOrEmail
      }
    };
    this.preOrderService.preOrderGearItem(preOrderForm);
  }

PreOrderComponent中,模板中包含以下内容:

<ng-container *ngIf="preOrderService.preOrder$ | async as preOrderItem">
  <div> TEST </div>
</ng-container>

PreOrderService中,我有以下内容:

    preOrderAction: BehaviorSubject<PreOrderForm> = new BehaviorSubject<
        PreOrderForm
      >(null);

      preOrder$ = this.preOrderAction.asObservable().pipe(
        switchMap((preOrderForm: PreOrderForm) => {
          console.log("PreORderTriggered");
          return this.preOrderGearItemAsync(preOrderForm);
        })
      );

    preOrderGearItem(preOrderForm: PreOrderForm) {
        console.log("Pre order form is:", preOrderForm);
        this.preOrderAction.next(preOrderForm);
      }

    preOrderGearItemAsync(preOrderForm: PreOrderForm): Observable<PreOrderForm> {
        if (preOrderForm === undefined) {
          return of(null);
        }
        return this.http
          .post<PreOrderForm>(
            `${this.merchandiseUrl}/${
              preOrderForm.orderDetails.gearItemId
            }/pre-order`,
            JSON.stringify(preOrderForm),
            this.headers
          )
}

问题是我无法触发http请求。我不确定自己在做什么错。

1 个答案:

答案 0 :(得分:0)

您的代码正在“运行”,如下面的堆栈闪电所示:https://stackblitz.com/edit/angular-nm5pcd

但是,我能否强调2点,并建议您做些改进?

1)服务启动时立即调用http请求(即使没有提交)

之所以发生,是因为BehaviourSubject的第一个“空”值,并且因为=== undefined应该是=== null。甚至更好的是,您可以使用filter运算符。

preOrder$ = this.preOrderAction.asObservable().pipe(
  filter((preOrderForm: PreOrderForm) => !!preOrderForm),
  switchMap((preOrderForm: PreOrderForm) => {
    return this.preOrderGearItemAsync(preOrderForm);
  })
); 

2)您还可以考虑另一种方式来调用您的帖子请求。

a)解决方案A

保持非常简单。 因此,只需从您的组件中调用service.preOrderGearItemAsync,进行订阅,检索结果并显示它即可。

this.preOrderService.preOrderGearItemAsync(preOrderForm).subscribe(response => {
  this.result = response;
});

b)解决方案B

https://stackblitz.com/edit/angular-nm5pcdNewPreOrderService所示。

您的组件可以调用方法preOrderGearItem,该方法通过订阅来调用http.get,然后在next上调用BehaviourSubject,以使最后的结果可用于您的组件。

希望这会有所帮助。