更新
我试图在这里制作一个独立版本:https ://codepen.io/neezer/pen/pPRJar
它不像我的本地副本那样工作,但我希望它足够相似,你可以看到我想要去哪里。
我也没有得到完全相同的行为,因为我将侦听器目标更改为document
,这似乎对一些人有所帮助。
另外,我正在使用 RxJS v5 和最新版本的 React。
仍然掌握RxJS的窍门......
我有两个 Observable:一个订阅了表格上的 mouseover x 坐标以显示调整大小的列,另一个允许用户在该列上拖动。
粗略地说,第一个看起来像这样(以下所有内容都定义在componentDidUpdate
React 组件的生命周期方法中):
Rx.DOM.mouseover(tableEl)
.map(/* some complicated x coordinate checking */)
.distinctUntilChanged()
.subscribe(/* setState call */)
这很好用,给了我这个:
所以现在我想提供实际的“拖动”行为,我尝试像这样设置一个新的 Observable
// `resizerEl` is the black element that appears on hover
// from the previous observable; it's just a div that gets
// repositioned and conditionally created
Rx.DOM.mousedown(resizerEl)
.flatMap(md => {
md.preventDefault()
return Rx.DOM.mousemove(tableEl)
.map(mm => mm.x - md.x)
.takeUntil(Rx.DOM.mouseup(document))
})
.subscribe(/* do column resizing stuff */)
这样做存在三个问题:
- 一旦我完成了我的第一次“拖动”,我就不能再做任何事情了。我的理解是
takeUntil
完成了 Observable,我不确定如何“重新启动”它。 - 当
mousemove
我拖动时,来自第一个可观察对象的仍然处于活动状态,因此一旦我的x
位置变化足以触发该行为,我的黑色 div 就会消失。 - 第二个 Observable 上的绑定似乎并不总是触发(它不可靠)。我认为这里可能存在竞争条件或发生的事情,因为有时我会刷新页面并且我会得到一次拖动(从#1),而其他时候我根本不会得到它。
请注意,在干净刷新后,我无法拖动句柄(#3),然后我刷新,我无法将句柄拖动到第一个 Observable 的边界设置之外——黑色的大小调整栏消失并重新出现为我的鼠标的 x 坐标进入和离开那个信封(#2)。
我一直在努力解决这个问题已经有一段时间了,并且非常感谢任何关于我在这里做错了什么的见解。简而言之,我想要
- 第一个 Observable 在我拖动时“暂停”,然后在我完成拖动时恢复
- 一旦拖动完成,第二个 Observable 不会“完成”(或“重新启动”)
- 第二个可靠工作的 Observable
正如我之前提到的,我目前在 React 组件的componentDidUpdate
生命周期方法中设置了这个逻辑,其形状大致如下所示:
componentWillUpdate() {
// bail if we don't have the ref to our table
if (!tableEl) {
return;
}
// try not to have a new Observable defined on each component update
if (!this.resizerDrag$ && this.resizer) {
this.resizerDrag$ = // second Observable from above
}
// try not to have a new Observable defined on each component update
if (!this.resizerPos$) {
this.resizerPos$ = // first Observable from above
}
}