2014-12-28 3 views
2

Я пытаюсь объединить перетаскиваемый компонент, используя Rx и React, используя различные статьи, примеры и т. Д. (Первый раз я пытался использовать Rxjs). До сих пор мой код былСобытия Reactjs, Rxjs и mouse

var Draggable = React.createClass({ 

    getInitialState: function() { 
    return { 
     x: 0, 
     y: 0 
    } 
    }, 

    componentDidMount: function() { 
    var dragTarget = $(this.getDOMNode()) 
    this.mouseup = Rx.Observable.fromEvent(dragTarget, 'mouseup') 
    this.mousemove = Rx.Observable.fromEvent(document, 'mousemove') 
    this.mousedown = Rx.Observable.fromEvent(dragTarget, 'mousedown') 

    this.mousedrag = this.mousedown.flatMap(function(md){   
     var startX = md.offsetX 
     var startY = md.offsetY 
     return this.mousemove.map(function(mm) { 
     mm.preventDefault() 
     return { 
      x: mm.clientX - startX, 
      y: mm.clientY - startY 
     } 
    }).takeUntil(this.mouseup) 
    }) 

    console.log(dragTarget) 
    console.log(this.mouseup) 
    console.log(this.mousemove) 
    console.log(this.mousedown) 
    console.log(this.mousedrag) 

    this.subscription = this.mousedrag.subscribe(function(pos){ <= Error here - No Listener Found 
    console.log(pos) 
    this.setState({ 
     x: pos.x, 
     y: pos.y 
    }) 
    this.props.onDrag(pos) 
    })  
}, 

    render: function() { 
    console.log("render:"+ this.state.x) 
    console.log("render:"+ this.state.y) 
    // transferPropsTo will merge style & other props passed into our 
    // component to also be on the child DIV. 
    return this.transferPropsTo(React.DOM.div({  
     style: { 
     position: 'absolute', 
     left: this.state.x + 'px', 
     top: this.state.y + 'px' 
     } 
    }, this.props.children)) 
    } 
}) 

Теперь я не уверен, правильно ли я это сделал. То, что я нахожу, заключается в том, что Rx не работает с ошибкой «Нет прослушивателя» на строке mousedrag.subscribe во время разговора о подписании. Console.log сообщает мне, что mouseup, mousemove и mousedown имеют неопределенные источники, но я не уверен, почему, поскольку dragTarget правильно - по-видимому - установлен на элемент DOM, лежащий в основе этого компонента, или, по крайней мере, элемент DOM (см. для пример, который я использовал).

Теперь я не уверен, где проблема. Я склонен думать, что событие componentDidMount показалось разумным местом для установки всей магии Rx (!). Но мне интересно, если я слишком рано, я должен быть привязан к этому где-то, совершать глупую ошибку или просто не думать прямо.

(Так что я попытался this jsfiddle и он не работает для меня тоже - но с другой ошибкой)

Любые предложения/исправления был бы весьма признателен

S

+0

Ссылка ПРМА в вашей скрипке ошибается - они дают 404. –

+0

@ColinRamsay делает http://jsfiddle.net/mattpodwysocki/d8bGW/2/ работы для вас? –

+0

Это работает: http://jsfiddle.net/d8bGW/4/ – Brandon

ответ

4

Я не работал с ReactJS, так что это может быть не полный ответ. Но самая очевидная проблема заключается в том, что у вас есть проблема контекста. В рамках локальных функций, которые вы используете для своих Rx-операций, this не будет установлен на ваш перетаскиваемый объект, и, действительно, все ваши свойства будут отсутствовать. Вы должны захватить в качестве переменной в своем закрытии, чтобы вы могли получить к ней доступ. См. Приведенную ниже переменную self:

Если это не поможет устранить проблему, уточните ошибку. Когда вы его получите? Во время разговора о подписке? Или только когда вы выдаете кусочек вашему элементу?

(кстати, вы должны listem к mouseup на document вместо dragTarget по тем же причинам, которые вы делаете это для mousemove).

componentDidMount: function() { 
    var dragTarget = $(this.getDOMNode()); 
    var self = this; 
    self.mouseup = Rx.Observable.fromEvent(document, 'mouseup'); 
    self.mousemove = Rx.Observable.fromEvent(document, 'mousemove'); 
    self.mousedown = Rx.Observable.fromEvent(dragTarget, 'mousedown'); 

    self.mousedrag = self.mousedown 
     .flatMap(function(md){   
      var startX = md.offsetX; 
      var startY = md.offsetY; 
      return self.mousemove 
       .map(function(mm) { 
        mm.preventDefault(); 
        return { 
         x: mm.clientX - startX, 
         y: mm.clientY - startY 
        }; 
       }) 
       .takeUntil(self.mouseup); 
     }); 

    console.log(dragTarget); 
    console.log(self.mouseup); 
    console.log(self.mousemove); 
    console.log(self.mousedown); 
    console.log(self.mousedrag); 

    self.subscription = self.mousedrag.subscribe(function(pos) { 
     console.log(pos) 
     self.setState({ 
      x: pos.x, 
      y: pos.y 
     }); 
     self.props.onDrag(pos); 
    }); 
}, 
+0

thx. Я добавил немного подробностей об ошибке в OP. Использование «Я», похоже, не имеет особого значения, и слушатель снова не найден. –

+0

Какую версию RxJs вы используете? В более старых версиях 'fromEvent' не поддерживал объекты jQuery. Более новые версии (до тех пор, как [useNativeEvents] (https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/config/readme.md#rxconfigusenativeevents) остаются «ложными»). Если вы используете более старую версию RxJs, попробуйте вызвать 'fromEvent' на' dragTarget [0] 'для передачи в свой собственный элемент DOM. – Brandon

+0

2.3.22 - однако, требуя rx-jquery (которого я раньше не использовал), а затем используя комбо ваш jsfiddle, и ваш ответ меня отсортировал. Brilliant. TVM (у меня нет достаточного количества ответов, чтобы откликнуться на ваш ответ!) –

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