【问题标题】:RxJs mousedrag complete callbackRxJs 鼠标拖动完成回调
【发布时间】:2015-11-01 07:31:41
【问题描述】:

我一直在尝试使用 RxJs 在基于画布的白板上替换鼠标事件侦听器。我的绘图效果很好,但由于某种原因,completed 函数永远不会被调用。

它非常简单,基于 RxJs 文档中的鼠标事件示例。这是代码的摘录,您可以在此处查看完整版本http://codepen.io/hanloong/pen/YyvqgM?editors=001

  point = (start, prev, current) ->
    start:      {x: start.offsetX, y: start.offsetY}
    previous:   {x: prev.offsetX, y: prev.offsetY}
    current:    {x: current.offsetX, y: current.offsetY}

  mouseup = Rx.Observable.fromEvent(document, 'mouseup')
  mousemove = Rx.Observable.fromEvent(document, 'mousemove')
  mousedown = Rx.Observable.fromEvent(document, 'mousedown')

  mousedrag = mousedown.flatMap (start) ->
    mousemove.zip mousemove.skip(1), (prev, current) ->
      point(start, prev, current)
    .takeUntil mouseup

  liveDraw = Rx.Observer.create(
    (pos) ->
      console.log pos
      # drawLine stage, shape, pos.previous, pos.current
    , (err) ->
      console.log "Error: #{err}"
    , () ->
      # never gets run
      console.log 'Complete'
  )

  mousedrag.subscribe liveDraw

目标是在用户完成绘图后将完整路径发送到服务器,这在理想情况下会发生在完成的回调中。此时是否可以检索整个集合,或者我应该在事件进入时构建另一个数组?

【问题讨论】:

  • 你可以在这里尝试类似的东西:stackoverflow.com/questions/22225810/…。或者,您可以尝试调试以查看发生了什么。参考:github.com/Reactive-Extensions/RxJS/blob/master/doc/…
  • 您是想在mousedrag observable 上调用takeUntil,还是在调用flatMap 时在压缩后的 observable 上调用takeUntil?它在你的咖啡脚本中不是很清楚(看看输出 js 显示它当前附加到通过调用 mousemove.zip 创建的可观察对象)。
  • takeUntilzip 上。如果我将其移至mousedrag,则确实会调用完整的回调,但缺点是我必须在每次鼠标拖动完成后创建一个新订阅(据我所知)。
  • 您是否在我提供给您的第一个链接中看到了答案,特别是使用repeat 运算符重新订阅mousedown
  • 是的,谢谢,添加repeat() 是一种享受。只是考虑用什么方法来收集整个鼠标拖动路径完成。

标签: coffeescript easeljs rxjs


【解决方案1】:

问题是您订阅的 Observable (mouseMove) 永远不会完成。 flatMap 运算符将吞下所有在您抬起鼠标按钮时生成的中间 onCompleted 事件。

我建议您将绘图作为副作用执行,然后将所有事件收集到一个数组中并在最后发送它们。抱歉,我不使用咖啡脚本,所以这是在 ES6 中:

var mouseup = Rx.Observable.fromEvent(document, 'mouseup');
var mousemove = Rx.Observable.fromEvent(document, 'mousemove');
var mousedown = Rx.Observable.fromEvent(document, 'mousedown');

var mousedrag = mousedown.flatMap(start => {
                  return mousemove
                           //Pair up the events
                           .pairwise()
                           .takeUntil(mouseup)
                           //Draw each event as you receive it
                           .tap(p => drawLine(stage, shape, pos[0], pos[1]))
                           //Gather all the events from this drag
                           .toArray();
                });

//Subscribe will now receive arrays for each drag that has occured
mousedrag.subscribe(sendDataToServer,
                    err => `Error: ${err}`);

要使用pairwise 运算符,您还需要包含rx.lite.coincidence.compat.js 文件。

【讨论】:

  • 谢谢 paulpdaniels,我会试试看。逻辑似乎很可靠
猜你喜欢
  • 2016-03-09
  • 2013-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多