仅在特定条件下触发 RXJS 流

huangapple go评论74阅读模式
英文:

Trigger RXJS Stream only on certain condition

问题

我在此提供翻译的代码部分:

detailsByAccount$: Observable<MyType> = this.selectedTab$.pipe(
  switchMap((tab) => {
     //通过表单提交的帐户
    return this.account$.pipe(
      switchMap((account) => {
        alert(`${account} -------- ${tab}`);
        // 发送服务器 HTTP 调用以获取响应
        if (tab === 'X') {
          return this.myService.getDetails(account)  
        }
        return this.myService.getOtherDetails(account);
      })
    );
  }),
);

如果您需要更多帮助,请随时提出。

英文:

I have two tabs on my UI.

First tab (default), there is one input textbox and when user submits it, a http call is sent to server

Second tab - Same input textbox + list of checkboxes out of which at least one has to be selected. Then on submit http call is sent.

Both of these cases work fine by themselves.

Now, the problem is - I want my stream to trigger only when form is submitted and not on tab switch. However, I do want the value of tab clicked.
However, currently after the form is submitted once, its being triggered on every tab switch as well ( probably because then it has both selected tab & account available).

Below is the code snippet.

I am not sure what i am missing. Any suggestions are highly appreciated.

detailsByAccount$: Observable&lt;MyType&gt; = this.selectedTab$.pipe(
switchMap((tab) =&gt; {
   //account$ = account submitted through form
  return this.account$.pipe(
    switchMap((account) =&gt; {
      alert(`${account} -------- ${tab}`);
      // Server Http call to get the response
      if (tab === &#39;X&#39;) {
        return this.myService.getDetails(account)  
      }
      return this.myService.getOtherDetails(account);
    })
  );
}),
);

答案1

得分: 1

我会这样做:

detailsByAccount$: Observable<MyType> = this.account$.pipe(
  withLatestFrom(this.selectedTab$),
  switchMap(([account, tab]) => {
    alert(`${account} -------- ${tab}`);
    // 调用服务器 Http 请求以获取响应
    if (tab === 'X') {
      return this.myService.getDetails(account);
    }
    return this.myService.getOtherDetails(account);
  })
);

withLatestFrom 操作符不会触发流,但当 account$ 被触发时,它会获取 selectedTab$ 的最新值并传递。但如果 selectedTab$ 尚未发出至少一次,它不会触发。

英文:

i would do it like this:

  detailsByAccount$: Observable&lt;MyType&gt; = this.account$.pipe(
    withLatestFrom(this.selectedTab$),
    switchMap(([account, tab]) =&gt; {
      alert(`${account} -------- ${tab}`);
      // Server Http call to get the response
      if (tab === &#39;X&#39;) {
        return this.myService.getDetails(account)  
      }
      return this.myService.getOtherDetails(account);
    })
  );

the withLatestFrom operator will not trigger the stream but when account$ is triggered, it will grab the latest value from selectedTab$ and pass it along. It will not trigger though if selectedTab$ has not emitted at least once.

答案2

得分: 0

以下是您要翻译的内容:

"所以对于这种情况,事实证明我必须使用BehaviorSubject,这使得事情变得有点棘手。以下是我最终使用的答案。始终欢迎任何改进/优化。

问题的前提 -
两个选项卡 -

  1. 输入表单。
  2. 带有复选框列表的输入表单。

不同的选项卡有不同的验证器。只要表单验证通过,就可以提交表单。

需要考虑的两个重要事项是 - 必须选择选项卡,并且流应该仅在提交表单后触发。

我的第一种方法在问题中提到了。但问题是,每次切换选项卡时都会进行http调用。

现在,为了修复它,我做的是 - 重新设计它,以便它总是在账户提交后触发,而不是在选项卡被选择后触发,然后我在内部流中使用了take(1),所以它每次都会自行完成。在我做了这个之后,这个问题得到了解决。

detailsByAccount$: Observable<MyType> = this.account$.pipe(
  switchMap((account) => {
    return this.selectedTab$.pipe(
      switchMap((tab) => {
        alert(`${account} -------- ${tab}`);
        // 服务器Http调用以获取响应
        if (tab === 'X') {
          return this.myService.getDetails(account);
        }
        return this.myService.getOtherDetails(account);
      }),
      take(1)
    );
  })
);

希望这对某人有所帮助。如果有人有更好的建议,请告诉我。

愿大家学有所成。

瓦特萨尔"

英文:

So for this scenario, turns out I had to use BehaviorSubject and it made things little tricky. Below is the answer that I ended up using. Any improvements/optimizations are always appreciated.

Premise of Question -
Two tabs –
Input form.
Input form with a list of checkboxes.

There is a different validator for different tabs. Whenever the form validation passes, form submit is enabled.

Two important things to consider are – Tab has to be selected and the stream should be triggered only after form is submitted.

My first approach was mentioned in the question. However, the issue was http call was being made on every tab switch.

Now, to fix it what I did was – I refactored it so it’s triggered always on account submitted rather than tab selected and then I used take(1) in the inner stream, so it completes itself every time. After I did this this issue got resolved.

detailsByAccount$: Observable&lt;MyType&gt; = this.account$.pipe(
  switchMap((account) =&gt; {
    return this.selectedTab$.pipe(
      switchMap((tab) =&gt; {
        alert(`${account} -------- ${tab}`);
        // Server Http call to get the response
        if (tab === &#39;X&#39;) {
          return this.myService.getDetails(account);
        }
        return this.myService.getOtherDetails(account);
      }),
  take(1)
 );
})
);

Hope this helps someone. If anyone has any better suggestions, please let me know.

Happy Learning

Vatsal

huangapple
  • 本文由 发表于 2020年1月3日 13:31:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/59573628.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定