Rxjs, fromEvent для обработки нескольких событий
Каков наилучший способ обработки нескольких событий на одном узле DOM в rxjs 5.1?
fromEvent($element, 'event_name')
но я могу указать только одно событие за раз.
Я хочу справиться scroll wheel touchmove touchend
События.
3 ответа
Вы можете использовать Rx.Observable.merge
функция для объединения нескольких наблюдаемых потоков в один поток:
// First, create a separate observable for each event:
const scrollEvents$ = Observable.fromEvent($element, 'scroll');
const wheelEvents$ = Observable.fromEvent($element, 'wheel');
const touchMoveEvents$ = Observable.fromEvent($element, 'touchmove');
const touchEndEvents$ = Observable.fromEvent($element, 'touchend');
// Then, merge all observables into one single stream:
const allEvents$ = Observable.merge(
scrollEvents$,
wheelEvents$,
touchMoveEvents$,
touchEndEvents$
);
Если это кажется немного раздутым, мы могли бы немного очиститься, создав массив для событий, а затем сопоставить этот массив с наблюдаемыми объектами. Это работает лучше всего, если вам не нужно ссылаться на события их связанных наблюдаемых отдельно в какой-то момент:
const events = [
'scroll',
'wheel',
'touchmove',
'touchend',
];
const eventStreams = events.map((ev) => Observable.fromEvent($element, ev));
const allEvents$ = Observable.merge(...eventStreams);
Теперь вы можете обрабатывать все события с помощью одной подписки:
const subscription = allEvents$.subscribe((event) => {
// do something with event...
// event may be of any type present in the events array.
});
Вот как я бы реализовал это в новейшей версии RxJs
const events = ['scroll', 'resize', 'orientationchange']
from(events)
.pipe(
mergeMap(event => fromEvent($element, event))
)
.subscribe(
event => // Do something with the event here
)
Вот как я предпочитаю комбинировать события:
fromEvents(dom, "scroll", "wheel", "touch", "etc...");
function fromEvents(dom, ...eventNames: string[]) {
return eventNames.reduce(
(prev, name) => Rx.merge(prev, fromEvent(dom, name)),
Rx.empty()
);
}
Как упоминалось выше, надеюсь, что ниже будет легче читать.
import {fromEvent, merge} from "rxjs";
const mousemoveEvent = fromEvent(document, 'mousemove');
const wheelEvent = fromEvent(document, 'wheel');
const leftclickEvent = fromEvent(document, 'auxclick');
const rightclickEvent = fromEvent(document, 'click');
const keyboardEvent = fromEvent(document, 'keydown');
const allEvents = merge(
mousemoveEvent, wheelEvent, leftclickEvent, rightclickEvent, keyboardEvent
)