From 014c20b4f4f2f1d3dbb2b0f8a3c2927672b5dd84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adina=20=C8=9Aeudan?= Date: Sat, 2 Oct 2021 23:38:08 +0300 Subject: [PATCH] Custom route reuse strategy --- src/lib/utils/custom-route-reuse.strategy.ts | 86 ++++++++++++++++++++ src/lib/utils/index.ts | 1 + 2 files changed, 87 insertions(+) create mode 100644 src/lib/utils/custom-route-reuse.strategy.ts diff --git a/src/lib/utils/custom-route-reuse.strategy.ts b/src/lib/utils/custom-route-reuse.strategy.ts new file mode 100644 index 0000000..2cc8956 --- /dev/null +++ b/src/lib/utils/custom-route-reuse.strategy.ts @@ -0,0 +1,86 @@ +import { ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy } from '@angular/router'; +import { Debounce } from '../utils'; + +export interface OnAttach { + ngOnAttach(previousRoute?: ActivatedRouteSnapshot): void; +} + +export interface OnDetach { + ngOnDetach(): void; +} + +interface RouteStorageObject { + handle: DetachedRouteHandle; + previousRoute: ActivatedRouteSnapshot; +} + +export class CustomRouteReuseStrategy implements RouteReuseStrategy { + private _storedRoutes: { [key: string]: RouteStorageObject } = {}; + + private static _removeTooltips(): void { + while (document.getElementsByTagName('mat-tooltip-component').length > 0) { + document.getElementsByTagName('mat-tooltip-component')[0].remove(); + } + } + + shouldDetach(route: ActivatedRouteSnapshot): boolean { + if (!route?.routeConfig?.data) { + return false; + } + return !!route.routeConfig.data.reuse && !!this._getKey(route); + } + + store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void { + if (handle === null) { + return; + } + CustomRouteReuseStrategy._removeTooltips(); + + const element: any = handle; + + if (element?.componentRef?.instance?.ngOnDetach) { + this._onDetach(element.componentRef?.instance); + } + + this._storedRoutes[this._getKey(route)] = { + handle: element as DetachedRouteHandle, + previousRoute: route + }; + } + + shouldAttach(route: ActivatedRouteSnapshot): boolean { + return !!this._storedRoutes[this._getKey(route)]; + } + + retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle { + const key = this._getKey(route); + const element: any = this._storedRoutes[key]?.handle; + + if (element?.componentRef?.instance?.ngOnAttach) { + this._onAttach(element.componentRef?.instance, this._storedRoutes[key].previousRoute); + } + + return element as DetachedRouteHandle; + } + + shouldReuseRoute(future: ActivatedRouteSnapshot, current: ActivatedRouteSnapshot): boolean { + return future.routeConfig === current.routeConfig || this._getKey(future) === this._getKey(current); + } + + private _getKey(route: ActivatedRouteSnapshot): string { + return route.pathFromRoot + .map((el: ActivatedRouteSnapshot) => (el.routeConfig ? (el.routeConfig.path as string) + JSON.stringify(el.params) : '')) + .filter(str => str.length > 0) + .join(''); + } + + @Debounce() + private _onAttach(instance: OnAttach, previousRoute?: ActivatedRouteSnapshot) { + instance.ngOnAttach(previousRoute); + } + + @Debounce() + private _onDetach(instance: OnDetach) { + instance.ngOnDetach(); + } +} diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts index 1b27d07..039abbc 100644 --- a/src/lib/utils/index.ts +++ b/src/lib/utils/index.ts @@ -13,3 +13,4 @@ export * from './decorators/on-change.decorator'; export * from './http-encoder'; export * from './types/iqser-types'; export * from './pruning-translation-loader'; +export * from './custom-route-reuse.strategy';