Reactjs RxJS DOM暂停可观察,而另一个;是否正在拖动;?
更新 我尝试在这里制作一个独立版本: 它和我的本地版本不太一样,但我希望它足够相似,你能看到我想要去的地方 我没有得到完全相同的行为,因为我将侦听器目标更改为Reactjs RxJS DOM暂停可观察,而另一个;是否正在拖动;?,reactjs,rxjs,rxjs-dom,Reactjs,Rxjs,Rxjs Dom,更新 我尝试在这里制作一个独立版本: 它和我的本地版本不太一样,但我希望它足够相似,你能看到我想要去的地方 我没有得到完全相同的行为,因为我将侦听器目标更改为document,这似乎对一些人有所帮助 另外,我正在使用RXJSV5和React的最新版本 仍然掌握着 我有两个可观察对象:一个订阅表上的mouseover x坐标以显示调整大小的列,另一个允许用户在该列上拖动 粗略地说,第一种方法看起来是这样的(在React组件中的componentDidUpdatelifecycle方法中定义了以下
document
,这似乎对一些人有所帮助
另外,我正在使用RXJSV5和React的最新版本
仍然掌握着 我有两个可观察对象:一个订阅表上的mouseover x坐标以显示调整大小的列,另一个允许用户在该列上拖动 粗略地说,第一种方法看起来是这样的(在React组件中的
componentDidUpdate
lifecycle方法中定义了以下所有方法):
这很有效,给了我这个:
所以现在我想提供实际的“拖动”行为,我试着建立一个新的可观察对象,就像这样
// `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 */)
这有三个问题:
一直持续到
完成可观察对象,我不确定如何“重新启动”它mousemove
仍处于活动状态,因此当我的x
位置发生足够的变化以触发该行为时,我的黑色div将消失我已经在这个问题上讨论了很长一段时间了,如果你能了解我到底做错了什么,我将不胜感激。简言之,我想要
- 当我拖动时,第一个观察到“暂停”,然后在完成拖动后恢复
- 拖动完成后,第二个可观察到的未“完成”(或“重新启动”)
- 第二个可观察到可靠工作
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
}
}
我现在已经对此进行了一些讨论,我不认为这个答案是完整的,但我想与大家分享我的见解。希望一个更先进的RxJS思维会出现,我们可以一起努力解决:) 我在CodePen中重新创建了一个“lite-er”版本,使用了一些轻jQuery操作,而不是React。以下是我目前掌握的情况: 第一个可观察到的在拖动时“暂停”,然后在完成拖动后恢复 解决第一个问题有助于解决其他两个问题。基于我为获得我的
resizerEl
所做的工作,我感觉它是在组件的render
方法中基于this.state
中的内容进行渲染的。如果这是真的,这意味着当第一个可观察对象仍然有能力创建和销毁resizerEl
,即使第二个可观察对象正在监听。这意味着,resizerEl
将不再能够生成任何事件,即使在鼠标移动之前,可观察对象不会完成
在我的例子中,我注意到如果你移动鼠标的速度足够快,超出了你试图拖动的宽度,它将消除resizerEl
,这是我们想要的,但不是在我们试图拖动某个东西的时候
我的解决方案:我在“组件”的“状态”中引入了另一个变量。当我们在resizerEl
上鼠标时,这将设置为true
,然后当我们再次向上鼠标时,这将设置为false
然后我们使用switchMap
Rx.DOM.mousemove(tableEl)
.switchMap(function(event) {
return this.state.mouseIsDown ? Rx.Observable.never() : Rx.Observable.of(event);
})
.map(...
也许有更好的方法来做,而不是仅仅把事件
放回一个可观察的位置,但这是我工作的最后一部分,我的大脑有点崩溃了。这里的关键是切换到可观察。当鼠标按下时,千万不要
,这样我们就不会在操作员链上走得更远
实际上,一件好事是,它甚至不需要放入this.state
,因为这会导致重新渲染。您可能只需要使用实例变量,因为该变量仅对Observables功能至关重要,而不是任何渲染。因此,使用this.mouseIsDown
也同样好
我们如何处理鼠标下降或上升
第1部分:
...
Rx.DOM.mousedown(resizerEl)
.do(() => this.mouseIsDown = true)
当然,最好将其抽象为一个函数,但这是它所做工作的要点
第2部分:
...
return Rx.DOM.mousemove(tableEl)
.map(mm => mm.x - md.x)
.takeUntil(Rx.DOM.mouseup(document))
.doOnCompleted(() => this.mouseIsDown = false)
在这里,我们利用doOnComplete
在观察对象完成后执行此副作用,在这种情况下,将在mouseup
上执行
拖动完成后,第二个可观察到的未“完成”(或“重新启动”)
现在有个棘手的问题,我从来没有遇到过这个问题。你看,每次Rx.DOM.mousedown(resizerEl)
发出一个事件,在flatMap
中,每次都会使用返回Rx.DOM.mousemove(tabele)…
创建一个新的可观察对象。我在做这个的时候使用了RxJS 4.1,所以可能会有行为上的差异,但是我发现,仅仅因为内部的可观察完成了,并不意味着外部的也会完成
那么会发生什么呢?好吧,我想既然您使用了React,那么当组件渲染时,resizerEl
将分别被创建/销毁。当然,我还没有看到您代码的其余部分,但是请纠正我
...
return Rx.DOM.mousemove(tableEl)
.map(mm => mm.x - md.x)
.takeUntil(Rx.DOM.mouseup(document))
.doOnCompleted(() => this.mouseIsDown = false)
if (!this.resizerDrag$ && this.resizer) {
this.resizerDrag$ = // second Observable from above
}
else if (!this.resizer && this.resizerDrag$) {
this.resizerDrag$ = null;
}