import { EventEmitter , Output , Input , Directive } from "@angular/core" ; import { ActivatedRoute } from "@angular/router" ; @ Directive ( { selector : 'fx-tracker' , exportAs : 'FxTracker' } ) export class FxTracker { @ Input ( ) value : any ; @ Input ( ) activatedRoute : ActivatedRoute ; @ Input ( ) orderArray : ( string | boolean | number ) [ ] ; @ Input ( ) history : any [ ] = [ ] ; @ Output ( ) historyChange : EventEmitter < any [ ] > = new EventEmitter ( ) ; @ Input ( ) index : number ; @ Output ( ) indexChange : EventEmitter < number > = new EventEmitter ( ) ; @ Input ( ) id : 0 | false | 1 | true ; loaded : boolean ; inFx : boolean ; orderIndex : number ; ngAfterViewInit ( ) { Promise . resolve ( ) . then ( ( ) => this . loaded = true ) ; } ngOnChanges ( changes ) { if ( changes . activatedRoute && changes . activatedRoute . currentValue ) { this . produceByRoute ( this . activatedRoute ) ; } else if ( changes . value ) { this . produceFxId ( this . value ) ; } } produceByRoute ( activatedRoute ) { const path = this . getRoutePath ( activatedRoute ) ; this . produceFxId ( path ) ; this . value = path ; } produceFxId ( value ) { this . history = this . history || [ ] ; if ( this . orderArray ) { this . id = this . produceOrderFxId ( value ) ; } else { this . index = this . index == null ? 0 : this . index ; const histLen = this . history . length ; const isBack = histLen && this . history [ this . index + 1 ] == value ; const isForward = histLen && this . history [ this . index - 1 ] == value ; if ( isBack ) { this . indexChange . emit ( ++ this . index ) ; this . id = this . id === 0 ? false : 0 ; return this . id ; } this . id = this . id === 1 ? true : 1 ; if ( isForward ) { this . indexChange . emit ( -- this . index ) ; return this . id ; } } this . history . splice ( this . index , 0 , value ) ; this . indexChange . emit ( this . index ) ; this . history . splice ( 25 , this . history . length ) ; this . historyChange . emit ( this . history ) ; return this . id ; } produceOrderFxId ( value ) { let oldIndex = 0 ; let newIndex = 0 ; const oldValue = this . orderArray [ this . orderIndex ] ; for ( let index = this . orderArray . length - 1 ; index >= 0 ; -- index ) { let item = this . orderArray [ index ] ; if ( value === item ) { newIndex = index ; } if ( oldValue === item ) { oldIndex = index ; } } this . orderIndex = newIndex ; if ( newIndex <= oldIndex ) { return this . id = this . id === 0 ? false : 0 ; } return this . id = this . id === 1 ? true : 1 ; } getRoutePath ( activatedRoute ) { let target = activatedRoute ; while ( target . firstChild ) target = target . firstChild ; return target . routeConfig . path ; } public delayOutFx ( ) { Promise . resolve ( ) . then ( ( ) => this . inFx = false ) ; } }