2017-09-26 333 views
0

使用RxJS,我想訂閱事件。問題是:我想在設置事件監聽器之前設置Observable。RxJS監聽事件但稍後附加事件監聽器

想想這就像兩個按鈕:Button1做了點擊事情,但只有在button2將一個事件偵聽器附加到button1之後。觀察者應該訂閱button1的點擊事件。所有這些應該在應用程序啓動時連接在一起。 Button2不應該設置觀察者!一些代碼,而無需RxJS:

button2.addEventListener('click', function() { 
    // [...] some code to prevent that button1 has more than one event listener 

    // attach event listener to button1 
    button1.addEventListener('click', clickHandler); 

    // now let observer subscribe itself to clickHandler somehow 
    // -> HOW? 
}); 


function clickHandler() { 
    console.log("clicked"); 
} 

編輯:也許,是可以觀察到某種從未發出任何假人事件處理程序的,但變成真正的事件處理程序(clickHandler)按鈕2被點擊後或類似的東西?!

編輯2:我注意到2個按鈕不是最好的例子。讓我們改變它,讓button2的事件偵聽器通過某種未知的機制進行連接。例如:

// is called by unkown means, i. e. the observer doesn't know how and when its attached 
function attach() { 
    button1.addEventListener('click', clickHandler); 
} 

但當attach()被調用時,觀察員應該訂閱clickHandler。或者,Observer可能會一直訂閱某個函數,attach()會將該函數與實際的事件偵聽器進行交換。不知道。

回答

1

所以當我知道你想創建一個可觀察到發射的 的button1每點擊一個項目,但只有在button2被點擊之前一段時間。

那麼這應該工作:

var button1 = document.querySelector('#button1'); 
 
var button2 = document.querySelector('#button2'); 
 

 
var onButton2Click$ = Rx.Observable.fromEvent(button2, 'click').take(1); 
 
var onButton1Click$ = Rx.Observable.fromEvent(button1, 'click').skipUntil(onButton2Click$); 
 

 

 
onButton1Click$.subscribe(function(event) { 
 
    console.log('button 1 clicked') 
 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.4.3/Rx.min.js"></script> 
 

 
<button id="button1">button 1</button> 
 
<button id="button2">button 2</button>

應該明確的fromEvent方法做什麼。

take運營商與參數1確保onButton2Click$ observable只發出1項,然後完成。

skipUntil運營商確保onButton1Click$可觀察只能開始發射項目,直到onButton2Click$可觀察到至少發射1個項目。

對於編輯的問題:

var button1 = document.querySelector('#button1'); 
 
var button2 = document.querySelector('#button2'); 
 

 
var onAttach$$ = new Rx.Subject(); 
 

 
function attach() { 
 
    onAttach$$.next(); 
 
    onAttach$$.complete(); 
 
} 
 

 
var onButton1Click$ = Rx.Observable.fromEvent(button1, 'click').skipUntil(onAttach$$); 
 

 
// for testing only 
 
button2.addEventListener('click', function(e) { 
 
    attach(); 
 
}); 
 

 
onButton1Click$.subscribe(function(event) { 
 
    console.log('button 1 clicked') 
 
}); 
 

 
onAttach$$.subscribe(function() { 
 
    console.log('attached listener') 
 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.4.3/Rx.min.js"></script> 
 

 
<button id="button1">button 1</button> 
 
<button id="button2">attach</button>

+0

感謝您抽出寶貴時間來回答。如果事件偵聽器沒有被button2附加,但是通過其他方式,你會怎麼做?如果沒有'take(1)'和'skipUntil()',這將如何工作?請參閱我的問題中的Edit2。 – ntaso

+0

我加了一個關於你的編輯的例子,用'Subject'來「附加」了監聽器。你不需要一個按鈕,這只是爲了測試這個例子。你爲什麼不做'skipUntil'呢?如果你想使用RxJs,那麼你應該使用它的方法。 – cyrix