【发布时间】:2017-09-24 03:55:43
【问题描述】:
更新
我尝试在这里制作一个独立版本:https://codepen.io/neezer/pen/pPRJar
它不像我的本地副本那样工作,但我希望它足够相似,你可以看到我想要去哪里。
我也没有得到完全相同的行为,因为我将侦听器目标更改为 document,这似乎对某些人有所帮助。
另外,我正在使用 RxJS v5 和最新版本的 React。
仍然掌握RxJS...
我有两个 Observable:一个订阅了鼠标悬停在表格上的 x 坐标以显示调整大小的列,另一个允许用户在该列上拖动。
粗略地说,第一个看起来像这样(以下所有内容都定义在 React 组件中的 componentDidUpdate 生命周期方法中):
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,我不确定如何“重新启动”它。 - 当我拖动时,来自第一个 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
}
}
【问题讨论】:
-
是否有可能获得一个 jsfiddle 或 jsbin 最小限度地复制问题。我对可能是什么有一些想法,但如果不进行一些调试就很难说。我只想说我没有看到您的代码有任何明显错误,但是缺少一些部分。
-
@paulpdaniels 用一个例子更新了我的问题,尽管它不是我原始代码的一对一。我尽力复制它,而不需要在我的实际应用中进行所有动态计算。