【问题标题】:Switching between two subscriptions in the ngOnInit() method在 ngOnInit() 方法中切换两个订阅
【发布时间】:2019-11-14 05:19:42
【问题描述】:

我有一个页面,我在其中将发票填充到网格中。在网格中有一个选项可以查看特定发票的付款。该按钮将用户从发票页面切换到付款页面,然后在该页面过滤所有付款,以便仅显示与该特定发票对应的付款。此外,当单击付款页面本身时,它会将所有付款填充到网格中。我在 ngOnInit() 方法中完成了这两件事,但是,我需要能够在两者之间切换。换句话说,我想在用户单击发票页面上的按钮以及当用户单击导航栏中的付款选项卡时过滤付款,我希望它显示所有付款。所以,我已经测试了这两个订阅并且知道它们可以工作,但是我怎样才能在两个订阅之间切换来完成这个呢?任何帮助表示赞赏。

我在 if 语句中使用了不同的变量和相等性检查,甚至尝试更改 if 语句的行位置,但没有占上风

ngOnInit() {
  this.sub = this.route.params.subscribe(
    params => {
      if (params == null) { //HERE LIES THE ISSUE
         this.invoiceNum = params['invoiceNum'];

         //displays FILTERED payments
        this.paymentService.showPayments(this.invoiceNum).subscribe(
        res => {
          this.payments = res.value;
          this.loading = false;
          console.log(res);
        },  
        err => {
          if (err.status == 401) {
            this.auth.logOut();
          }
          this.loading = false;
          console.log(err);
        }
      );
    } else {

      //displays ALL payments
      this.paymentService.getPayments().subscribe(
        res => {
          this.payments = res.value;
          this.loading = false;
          console.log(res);
        },
        err => {
          if (err.status == 401) {
            this.auth.logOut();
          }
          this.loading = false;
          console.log(err);
        }
      );
    }
   }
 );
}

【问题讨论】:

  • 为什么要测试 params 是否为空?首先,它永远不会为null,其次,如果它为null,它怎么可能包含参数invoiceNum?为什么不直接获取 invoiceNum 参数,然后测试是否定义了 that 参数?另外,不要复制所有代码。两个分支之间的唯一区别是你如何获得 observable。
  • 在每个 http 调用中测试 401 也是您真正不应该做的事情。这应该在拦截器中,一劳永逸。
  • 感谢您的建议和最佳编码实践 JB。澄清一下,当您说获取 invoiceNum 参数时,您的意思是类似于 this.invoiceNum 的意思吗?
  • 不,我是说params['invoiceNum']

标签: angular typescript ngoninit


【解决方案1】:

您可以使用switchMapswitchMap 可以为一个条件返回不同的主题。

此解决方案将Route Parameter Changes 主题切换为HTTP Request for payments 主题。如果路由器参数包含invoiceNum,它将返回invoiceNum 的特定付款主题。或者,它将返回所有付款的主题。

您可以在这两种情况下重复使用 onNext/onError 回调。

ngOnInit() {
  this.sub = this.route.params
  .pipe(
    switchMap(params => {
      if (params['invoiceNum'] !== undefined) {
        //displays FILTERED payments
        return this.paymentService.showPayments(this.invoiceNum);
      } else {
        //displays ALL payments
        this.paymentService.getPayments();
      }
    })
  )
  // Reuse onNext/onError callbacks
  .subscribe(
    res => {
      this.payments = res.value;
      this.loading = false;
      console.log(res);
    },  
    err => {
      if (err.status == 401) {
        this.auth.logOut();
      }
      this.loading = false;
      console.log(err);
    }
  );
}

【讨论】:

  • 感谢黑猫你的建议。我试图将它实现到我的代码中,但收到以下错误“类型'{}'上不存在属性'值'。”我删除了 .value 以查看是否会关闭编译器,但随后我得到“类型'{}'缺少类型'any []'的以下属性:长度、弹出、推送、连接和更多 26 个。”有任何想法吗?我没有太多的在线资源来帮助解决这个问题。再次感谢。
  • 只是类型错误。请告诉我this.paymentService.showPayments(this.invoiceNum)this.paymentService.getPayments() 的类型。他们通常拥有value 的属性吗?
  • 它们都返回任何类型的 REST api GET 请求
猜你喜欢
  • 1970-01-01
  • 2019-10-25
  • 2022-07-31
  • 1970-01-01
  • 2019-01-03
  • 2018-06-12
  • 2019-09-02
  • 2019-10-06
  • 2019-01-25
相关资源
最近更新 更多