web-dev-qa-db-fra.com

Rxjs, fromEvent pour gérer plusieurs événements

Quel est le meilleur moyen de gérer plusieurs événements sur le même nœud DOM dans rxjs 5.1?

fromEvent($element, 'event_name') mais je ne peux spécifier qu'un seul événement à la fois.

Je veux gérer les événements scroll wheel touchmove touchend.

7
user3130446

Vous pouvez utiliser la fonction Rx.Observable.merge pour fusionner plusieurs flux observables en un seul flux:

// 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$
);

Si cela vous semble un peu gonflé, nous pouvons nettoyer un peu en créant un tableau pour les événements, puis en mappant ce tableau sur des objets observables. Cela fonctionne mieux si vous n'avez pas besoin de référencer les événements leurs observables associés séparément à un moment donné:

const events = [
    'scroll',
    'wheel',
    'touchmove',
    'touchend',
];

const eventStreams = events.map((ev) => Observable.fromEvent($element, ev));
const allEvents$ = Observable.merge(...eventStreams);

Vous pouvez maintenant gérer tous les événements avec un seul abonnement:

const subscription = allEvents$.subscribe((event) => {
    // do something with event...
    // event may be of any type present in the events array.
});
23
Jeffrey Westerkamp

Voici comment je préfère combiner des événements:

fromEvents(dom, "scroll", "wheel", "touch", "etc...");
function fromEvents(dom, ...eventNames: string[]) {
    return eventNames.reduce(
        (prev, name) => Rx.merge(prev, fromEvent(dom, name)),
        Rx.empty()
    );
}
2
Ibrahim ben Salah

Voici comment je mettrais cela en œuvre dans la nouvelle version de RxJs

const events = ['scroll', 'resize', 'orientationchange']
from(events)
  .pipe(
    mergeMap(event => fromEvent($element, event))
  )
  .subscribe(
    event => // Do something with the event here
  )
1
user3679814