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

nta*_*aso 2 javascript events rxjs

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

把这想象成两个按钮: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");
}
Run Code Online (Sandbox Code Playgroud)

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

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);
}
Run Code Online (Sandbox Code Playgroud)

但是当attach()被调用时,观察者应该订阅clickHandler. 或者,观察者可能一直订阅某个函数,并attach()用实际的事件侦听器替换该函数。不知道。

cyr*_*r_x 6

因此,据我所知,您想创建一个 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')
});
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

应该很清楚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')
});
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)