[英]RxJS mouseenter between first and second clicks
我正在尝试捕获列表中任何项目的第一次和第二次单击之间的项目列表上的悬停事件。
例如
我设置了一个可观察的流,如下所示:
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.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
我确信问题出在流的非惯用用法上,但不确定为什么。
看来您可能正在尝试将命令式方法强制引入功能性编程库中,这就是为什么使其变得如此复杂使其起作用的原因。 这可能更简单:
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的一般建议,请尝试查找声明性解决方案。 如果您开始思考如何转换流以获取所需内容,而不是执行该操作的步骤,事情将会变得更加容易。
希望对您有帮助,祝您好运!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.