在RX.js中加入两个可观察对象

在RX.js中加入两个可观察对象

问题描述:

我试图根据另外两个对象创建新的可观察对象。我有:在RX.js中加入两个可观察对象

var mouseClickObservable = Rx.Observable.fromEvent(this.canvas, "click"); 
var mouseMoveObservable = Rx.Observable.fromEvent(this.canvas, "mousemove"); 
function findObject(x, y) {/* logic for finding object under cursor here. */} 
var objectUnderCursor = this.mouseMoveObservable.select(function (ev) { 
    return findObject(ev.clientX, clientY); 
}); 

我想创建objectClicked观察到,当用户点击一个对象应该产生价值。我可以再次调用findObject,像这样:

var objectClicked = this.mouseClickObservable.select(function (ev) { 
    return findObject(ev.clientX, clientY); 
}); 

但它是非常耗时的功能。

我目前使用的另一种方法是将最后一个悬停的对象存储在一个变量中,但我认为应该有这样做的纯粹的功能方式。我tryed使用Observable.join这样的:

var objectClicked = this.objectUnderCursor.join(
    mouseClickObservable, 
    function (obj) { return this.objectUnderCursor }, 
    function (ev) { return Rx.Observable.empty() }, 
    function (obj, ev) { return obj }) 

但它点击

我看不出你居然订阅任何你定义了这些可观的任何代码多个值,所以很难提供一个好的答案。您是否真的需要在每次鼠标移动时拨打findObject?您是否需要在鼠标移动时提供某种悬停效果?或者你只需​​要知道被点击的对象,在这种情况下,只需点击一次就拨打findObject一次?

假设你只需要知道被点击的对象是什么,你甚至不担心鼠标移动,只是这样做:

var objectClicked = mouseClickObservable 
    .select(function (ev) { return findObject(ev.clientX, ev.clientY); }); 

objectClicked.subscribe(function(o) { ... }); 

如果你确实需要知道的对象鼠标悬停,但是想要避免在点击时调用昂贵的点击测试,那么确实需要存储中间值(无论如何您都需要存储这些值以进行悬停效果)。您可以使用BehaviorSubject用于此目的:

this.objectUnderCursor = new Rx.BehaviorSubject(); 
mouseMoveObservable 
    .select(function (ev) { return findObject(ev.clientX, ev.clientY); }) 
    .subscribe(this.objectUnderCursor); 


this.objectUnderCursor.subscribe(function (o) { do your hover effects here }); 
mouseClickObservable 
    .selectMany(function() { return this.objectUnderCursor; }) 
    .subscribe(function (o) { do your click effect }); 
+0

是的,我需要知道什么鼠标悬停,和你最后的解决方案是非常有益的,但观察到由'.selectMany创建(函数(){返回this.objectUnderCursor ;})'当鼠标在点击后移动时,'会继续产生值。我将它改为'.selectMany(function(){return this.objectUnderCursor.first();})',它完美地工作。非常感谢! –