0

我試圖根據另外兩個對象創建新的可觀察對象。我有:在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 }) 

但它點擊

回答

0

我看不出你居然訂閱任何你定義了這些可觀的任何代碼多個值,所以很難提供一個好的答案。您是否真的需要在每次鼠標移動時撥打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();})',它完美地工作。非常感謝! –

相關問題