在订阅之前如何使用Observable有条件地做某事?

时间:2017-05-18 05:04:44

标签: angular rxjs angular2-observables

我正在尝试实施执行以下步骤的解决方案:

  1. 使用filter检查条件是否有效。
  2. 检查是否按下Ctrl并执行某些功能。
  3. 最后,执行另一个功能。
  4. 我能够使用该代码:

    const click = Observable.fromEvent(element, 'click');
    click.filter(() => condition)
         .do((event: MouseEvent) => {
             if (!event.ctrlKey) {
                 // maybe do something...
             }
         }).subscribe(() => {
             // aways do something else at end
         });
    

    我想知道是否有更优雅的解决方案可以删除do方法中的if条件?

2 个答案:

答案 0 :(得分:1)

我不确定我是否理解这个问题,但这是一种类似的方法,并尽量保持代码尽可能干净:

const click$ = Observable.fromEvent(document, 'click');

// I don't know what's in your condition so I just return true
const condition = () => true;

const fnCtrlIsPressed = () => 'Ctrl is pressed';
const fnCtrlIsNotPressed = () => 'Ctrl is not pressed';

click$
  .map(event => event.ctrlKey)
  .map(isCtrlPressed => isCtrlPressed ?
    fnCtrlIsPressed():
    fnCtrlIsNotPressed())
  .do(console.log)
  .subscribe();

输出将是这样的:
enter image description here

这是一个有效的Plunkr:https://plnkr.co/edit/VwuXkk0QnVGC4hPCvtOo?p=preview

答案 1 :(得分:0)

一个选项是flatMap,其中一个流会在按下Ctrl的情况下触发相应的操作,与您的方法没什么不同。

const condition = () => true;

const clickStreamWithCtrlAction = Observable.fromEvent(element, "click")
  .flatMap(event => event.ctrlKey
    ? Observable.of(event).do(clickWithCtrl => console.log("With ctrl clause"))
    : Observable.of(event)
  )

clickStreamWithCtrlAction
    .filter(condition)
    .subscribe(event => console.log(`Finally clause, ctrlKey: ${event.ctrlKey}`));