RxJs mousedrag完成回调

时间:2015-10-30 00:07:00

标签: coffeescript easeljs rxjs

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

它非常简单,基于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

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

1 个答案:

答案 0 :(得分:1)

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

我建议您将绘图作为副作用执行,然后将所有事件收集到一个数组中并在最后发送它们。道歉我没有使用coffeescript所以这是在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文件。