RxJS监听事件但稍后附加事件监听器

时间:2017-09-26 08:47:16

标签: javascript events rxjs

使用RxJS,我想订阅活动。问题是:我想在设置事件监听器之前设置Observable。

将此视为两个按钮:Button1在单击时执行某些操作,但仅在button2将事件侦听器附加到button1之后。观察者应该订阅button1的click事件。所有这些应该在应用程序启动时连接在一起。 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");
}

编辑:也许,是否有可能观察到某种从未发出任何东西的虚拟事件处理程序,但在点击button2之后变成真实的事件处理程序(clickHandler)?或者类似的东西?!

Edit2:我注意到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 个答案:

答案 0 :(得分:2)

据我了解你想要创建一个发出项目的Observable 每次点击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方法的作用。

参数1的{​​{3}}运算符可确保onButton2Click$可观察量只发出1个项目,然后完成。

take运算符确保onButton1Click$ observable仅开始发出项目,直到onButton2Click$ observable发出至少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>