To read more about reactive extensions, you can follow the link http://reactivex.io/intro.html. In short, reactive extensions represent a way to compose event-based solutions using observables. It’s a model that treats streams of asynchronous events using a simple composable approach.
Reactive extensions extend the observer patter to support sequences of data and events and it allows us to compose them directly.
With pipes we can combine multiple functions into a single function, and in our example, we would like to use the debounce operation to delay our search. https://rxjs-dev.firebaseapp.com/api/operators/debounce
Now…we can do this on every operation, or we can use the power of directives. As the “guide” says, use directive to attach events, and this is exactly what we are doing
import { Directive, Input, Output, EventEmitter, HostListener } from '@angular/core'; import { Observable, Subject, interval } from 'rxjs'; import { debounce } from 'rxjs/operators'; @Directive({ // tslint:disable-next-line: directive-selector selector: '[cxDebounceKeyUp]' }) export class CxDeboundeKeyUpDirective { // emission data public NewEventSubject = new Subject<KeyboardEvent>(); public NewEvent: Observable<KeyboardEvent>; @Input() public Interval = 300; @Output() public DebouncedEvent = new EventEmitter<KeyboardEvent>(); @HostListener('keyup',['$event']) public OnKeyUp(ev: KeyboardEvent) { this.NewEventSubject.next(ev); } constructor() { this.NewEvent = this.NewEventSubject.pipe(debounce(() => interval(this.Interval))); this.NewEvent.subscribe(value => { this.DebouncedEvent.emit(value); }); } }
Pretty simple. And we have a major advantage in using a directive instead of wrapping all up in a custom component, we get to leverage all the functionality of our input element without having to write layers of wrappers on top of it.
Usage
><input matInput cxDebounceKeyUp (DebouncedEvent)="applyFilter($event)" placeholder="Workspace name" #input />