import { Directive , ElementRef , OnInit , NgZone , OnDestroy , Output , EventEmitter , Input } from '@angular/core' ; import { Subject , Observable , Observer , fromEvent , Subscription } from 'rxjs' ; import { takeUntil , tap } from 'rxjs/operators' ; import { coerceBooleanProperty } from 'ngx-tethys/util' ; @ Directive ( { selector : '[thyScroll]' } ) export class ThyScrollDirective implements OnInit , OnDestroy { private _destroyed = new Subject ( ) ; private _enable = true ; private _initialled = false ; private _subscription : Subscription ; private _elementScrolled : Observable < Event > = new Observable ( ( observer ) => this . ngZone . runOutsideAngular ( ( ) => fromEvent ( this . elementRef . nativeElement , 'scroll' ) . pipe ( takeUntil ( this . _destroyed ) ) . subscribe ( observer ) ) ) ; @ Input ( ) set thyEnable ( value ) { this . _enable = coerceBooleanProperty ( value ) ; if ( this . _initialled ) { if ( this . _enable && this . _subscription === null ) { this . _subscription = this . _elementScrolled . subscribe ( ( ) => this . thyOnScrolled . emit ( this . elementRef ) ) ; } else { if ( this . _subscription ) { this . _subscription . unsubscribe ( ) ; this . _subscription = null ; } } } } @ Output ( ) thyOnScrolled : EventEmitter < ElementRef > = new EventEmitter < ElementRef > ( ) ; constructor ( private elementRef , private ngZone ) { } ngOnInit ( ) { if ( this . _enable ) { this . _subscription = this . _elementScrolled . subscribe ( ( ) => this . thyOnScrolled . emit ( this . elementRef ) ) ; } this . _initialled = true ; } ngOnDestroy ( ) { this . _destroyed . next ( ) ; this . _destroyed . complete ( ) ; } getElementRef ( ) { return this . elementRef ; } }