54 lines
1.6 KiB
TypeScript
54 lines
1.6 KiB
TypeScript
import {
|
|
Injectable,
|
|
OnDestroy
|
|
} from '@angular/core';
|
|
import {
|
|
CanActivate,
|
|
NavigationEnd,
|
|
NavigationStart,
|
|
Router,
|
|
} from '@angular/router';
|
|
|
|
import { Subscription } from 'rxjs';
|
|
import {
|
|
filter,
|
|
pairwise,
|
|
} from 'rxjs/operators';
|
|
|
|
@Injectable()
|
|
export class DebounceNavigationService implements CanActivate, OnDestroy {
|
|
navigationStartSub: Subscription;
|
|
navigationSuccessSub: Subscription;
|
|
|
|
private lastNavigation: NavigationStart;
|
|
private thisNavigation: NavigationStart;
|
|
private lastNavigationSuccessId: number;
|
|
|
|
constructor(private router: Router) {
|
|
this.navigationStartSub = this.router.events
|
|
.pipe(filter(event => event instanceof NavigationStart), pairwise())
|
|
.subscribe((events: [NavigationStart, NavigationStart]) => [this.lastNavigation, this.thisNavigation] = events);
|
|
|
|
this.navigationSuccessSub = this.router.events
|
|
.pipe(filter(event => event instanceof NavigationEnd))
|
|
.subscribe((event: NavigationEnd) => this.lastNavigationSuccessId = event.id);
|
|
}
|
|
|
|
async canActivate() {
|
|
return !(this.thisNavigation?.navigationTrigger === 'hashchange' &&
|
|
this.lastNavigation.navigationTrigger === 'popstate' &&
|
|
this.lastNavigationSuccessId === this.lastNavigation.id &&
|
|
this.lastNavigation.url === this.thisNavigation?.url);
|
|
}
|
|
|
|
ngOnDestroy() {
|
|
if (this.navigationStartSub != null) {
|
|
this.navigationStartSub.unsubscribe();
|
|
}
|
|
|
|
if (this.navigationSuccessSub != null) {
|
|
this.navigationSuccessSub.unsubscribe();
|
|
}
|
|
}
|
|
}
|