【问题标题】:How to do something conditionally with Observables before subscribe?在订阅之前如何有条件地使用 Observables 做一些事情?
【发布时间】:2017-05-18 05:04:43
【问题描述】:

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

  1. 使用filter 检查条件是否有效。
  2. 检查Ctrl是否被按下,如果是则执行一些功能。
  3. 最后,执行另一个函数。

我能够使用该代码使其工作:

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 条件?

【问题讨论】:

  • 合并do和subscribe怎么样? click.filter(...).subscribe((event: MouseEvent) => { ... })

标签: angular rxjs angular2-observables


【解决方案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();

输出将是这样的:

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

【讨论】:

    【解决方案2】:

    一种选择是使用流进行平面映射,以在按下 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}`));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多