import { Directive , OnInit , Input , ElementRef , Renderer2 , ContentChildren , QueryList , AfterContentInit , Optional } from '@angular/core' ; import { Router , NavigationEnd } from '@angular/router' ; import { filter , takeUntil } from 'rxjs/operators' ; import { Subject } from 'rxjs' ; import { ActionDirective } from './action.directive' ; @ Directive ( { selector : '[acaActiveLink]' , exportAs : 'acaActiveLink' } ) export class ActiveLinkDirective implements OnInit , AfterContentInit { @ Input ( ) acaActiveLink ; @ ContentChildren ( ActionDirective , { descendants : true } ) links : QueryList < ActionDirective > ; isLinkActive = false ; private onDestroy$ : Subject < boolean > = new Subject < boolean > ( ) ; constructor ( private router , private element , private renderer , @ Optional ( ) private action ? ) { } ngOnInit ( ) { this . router . events . pipe ( filter ( ( event ) => event instanceof NavigationEnd ) , takeUntil ( this . onDestroy$ ) ) . subscribe ( ( event ) => { this . update ( event . urlAfterRedirects ) ; } ) ; } private update ( url ) { if ( this . action ) { const itemUrl = this . resolveUrl ( this . action ) ; this . render ( url , itemUrl ) ; } this . links . map ( ( item ) => { const itemUrl = this . resolveUrl ( item ) ; this . render ( url , itemUrl ) ; } ) ; } private render ( routerUrl , actionUrl ) { if ( routerUrl && routerUrl . substring ( 1 ) . startsWith ( actionUrl ) ) { this . isLinkActive = true ; this . renderer . addClass ( this . element . nativeElement , this . acaActiveLink ) ; } else { this . isLinkActive = false ; this . renderer . removeClass ( this . element . nativeElement , this . acaActiveLink ) ; } } ngAfterContentInit ( ) { this . links . changes . subscribe ( ( ) => this . update ( this . router . url ) ) ; this . update ( this . router . url ) ; } private resolveUrl ( item ) { return ( item . action && item . action . click && item . action . click . payload ) || item . action . route ; } }