【问题标题】:RxJS mouseenter between first and second clicksRxJS mouseenter 在第一次和第二次点击之间
【发布时间】:2017-02-25 00:05:43
【问题描述】:

我正在尝试在列表中任何项目的第一次和第二次单击之间捕获项目列表上的悬停事件。

例如

  • 用户点击列表中的项目
  • 悬停流项目发出事件
  • 用户在列表中执行第二次点击和悬停事件停止

我已经设置了一个可观察的流如下:

let items = document.getElementsByClassName("item");
let itemClicks = Rx.Observable.fromEvent(items, "click");
let itemHover = Rx.Observable.fromEvent(items, "mouseenter");

let clicksWithFlag = itemClicks.scan((acc, val) => ({ val: val.target.innerHTML, firstClick: !acc.firstClick}), {});

//create stream of 1st clicks
let firstClicks = clicksWithFlag.filter(x => x.firstClick).pluck('val');
//create stream of second clicks
let secondClicks = clicksWithFlag.filter(x => !x.firstClick).pluck('val');

let hoverBetweenFirstAndSecondClick = firstClicks.flatMap(x => itemHover.takeUntil(secondClicks));

我遇到的问题是itemHover.takeUntil(secondClicks) 没有结束 itemHover 流。我认为它与来自同一个可观察对象的 firstClicks 和 secondClicks 有关,但无法弄清楚。

如果我将 takeUntil(secondClicks) 交换为任何其他流(例如停止按钮),它会起作用。

请参阅此 JSBin 示例:https://jsbin.com/dotapis/edit?js,console,output

希望有人可以提供帮助。我正在尝试使用 RxJS 构建一个范围选择器,但我开始认为将流分成第一次和第二次点击可能不是最好的路线。

更新

刚刚用 BaconJS 试过这个,我可以用几乎完全相同的代码让它工作。 https://jsbin.com/fobumu/edit?js,console,output

我确信问题在于流的非惯用用法,但不确定原因。

【问题讨论】:

    标签: javascript rxjs


    【解决方案1】:

    看来您可能试图将命令式方法强加到函数式编程库中,这就是使其工作变得如此复杂的原因。 这可能更简单:

    let items = document.getElementsByClassName("item");
    let button = document.getElementById("button1");
    
    let itemClicks = Rx.Observable.fromEvent(items, 'click');
    let itemHover = Rx.Observable.fromEvent(items, 'mouseenter');
    
    let buttonClicks = Rx.Observable.fromEvent(button, 'click');
    
    let clicksWithFlag = itemClicks.scan((acc, val) => (
      { val: val.target.innerHTML, firstClick: !acc.firstClick}
    ), {});
    
    clicksWithFlag
      .combineLatest(itemHover, (click, hover) => ({click, hover}))
      .filter(arg => arg.click.firstClick)
      .map(arg => arg.hover.target.innerHTML)
      .subscribe(hover => console.warn('btn: hover: ' + hover));
    

    作为使用 Rx 时的一般建议,请尝试找到声明式解决方案。如果您开始考虑如何转换流以获得所需的内容,而不是执行步骤,那么事情会变得更容易。

    希望对你有帮助,祝你好运!

    【讨论】:

    • 谢谢。我尝试遵循与我在 RXJs 文档中看到的类似的模式。仍然有点困惑为什么它在 BaconJS 而不是 RXJs 中有效。
    猜你喜欢
    • 1970-01-01
    • 2017-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多