2015-10-30 3 views
1

Я играл с RxJs, пытаясь заменить прослушиватели событий мыши на доске на холсте. У меня рисунок отлично работает, но по какой-то причине завершена функция никогда не вызывается.RxJs mousedrag полный обратный вызов

Это довольно простой и основанный на примере события мыши в документах 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

Возможно, вы можете попробовать что-то вроде здесь: http://stackoverflow.com/questions/22225810/rxjs-draw-line-on-html5-canvas?rq=1. Кроме того, вы можете попробовать отладить, чтобы узнать, что происходит. Cf: https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/testing.md – user3743222

+0

Вы пытаетесь называть 'takeUntil' на наблюдаемом наблюдателе' mousedrag 'или на zipped, наблюдаемом в вашем вызове к 'flatMap'? Его не очень ясно видно в вашем coffeescript (посмотрите на выход js, показывая его прикрепленный к настоящему времени наблюдаемый, созданный вызовом 'mousemove.zip'). –

+0

'takeUntil' находится на' zip'. Полный обратный вызов вызывает вызов, если я перехожу к «mousedrag», но недостатком этого является то, что мне нужно будет создать новую подписку после завершения каждого перетаскивания мышью (насколько я могу судить). –

ответ

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, а также.

+0

Спасибо, paulpdaniels, я попробую. Логика кажется солидной –

Смежные вопросы