Reactjs、Rxjs 和鼠标事件

Reactjs, Rxjs and mouse events

本文关键字:鼠标 事件 Rxjs Reactjs      更新时间:2023-09-26

我正在尝试使用各种文章,示例等使用Rx和React拼凑出一个可拖动的组件(我第一次尝试使用Rxjs)。到目前为止,我的代码是

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 行上出现"找不到侦听器"错误而失败。控制台.log告诉我鼠标向上,鼠标移动和鼠标向下都有未定义的源 - 但我不确定为什么,因为dragTarget正确 - 显然 - 设置为该组件下的DOM元素或至少是一个DOM元素(请参阅此处我从中得出的示例)。

现在我不确定问题出在哪里。我倾向于认为组件DidMount事件似乎是设置所有Rx魔法(!但我想知道我是否还为时过早,我应该在某个地方绑定这个,犯一个愚蠢的错误,或者只是没有弄清楚。

(所以我也尝试了这个 jsfiddle,它也对我不起作用 - 但有一个不同的错误)

任何建议/更正将不胜感激

S

我没有

使用过ReactJS,所以这可能不是完整的答案。 但最明显的问题是你有一个上下文问题。 在用于 Rx 操作的本地函数中,this不会设置为可拖动对象,实际上所有属性都将丢失。 您需要将this捕获为闭包中的变量,以便可以访问它。 请参阅下面的self变量:

如果这不能解决您的问题,请详细说明您的错误。 你到底什么时候得到它? 在通话期间订阅? 还是仅在向元素发出鼠标按下时?

(顺便说一句,你应该在documentmouseup而不是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);
    });
},