Created
July 7, 2021 08:09
-
-
Save Purecaesar/5727a3009b48d0ab69e7a45af107244a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { ChangeDetectorRef, ComponentRef } from '@angular/core'; | |
import { OutletContext, Router } from '@angular/router'; | |
import { Subject } from 'rxjs'; | |
import { pluck, switchMap, takeUntil } from 'rxjs/operators'; | |
import { getCurrentOutlet } from '../functions/get-current-outlet'; | |
import { getRouteWithData } from '../functions/get-route-with-data'; | |
import { StaticInjectorService } from '../services/static-injector.service'; | |
export function NgResolve(name?: string, propagation = true) { | |
return function( | |
target: any, | |
key: string, | |
originalDescriptor?: TypedPropertyDescriptor<any> | |
): any { | |
const router = StaticInjectorService.Injector.get(Router); | |
const triger = new Subject(); | |
const destroyer = new Subject(); | |
const rootContextMap = (router as any).rootContexts.contexts as Map< | |
string, | |
OutletContext | |
>; | |
let routerData: any; | |
let cdr: ChangeDetectorRef; | |
let inited = false; | |
let compRef: ComponentRef<any>; | |
triger | |
.pipe( | |
switchMap(() => { | |
const currentActivatedOutlet = getCurrentOutlet( | |
rootContextMap, | |
target.constructor | |
); | |
if (!currentActivatedOutlet) | |
throw new Error('Component is not in router tree'); | |
const outlet: any = currentActivatedOutlet.outlet; | |
const routeWithData = getRouteWithData( | |
currentActivatedOutlet.route, | |
name || key, | |
propagation | |
); | |
compRef = outlet.activated as ComponentRef<any>; | |
cdr = compRef.injector.get(ChangeDetectorRef); | |
compRef.onDestroy(() => { | |
inited = false; | |
destroyer.next(); | |
}); | |
return routeWithData.data.pipe( | |
pluck(name || key), | |
takeUntil(destroyer) | |
); | |
}) | |
) | |
.subscribe({ | |
next: data => { | |
target[key] = data; | |
cdr.markForCheck(); | |
} | |
}); | |
return { | |
get() { | |
if (!inited) { | |
inited = true; | |
triger.next(); | |
} | |
return originalDescriptor | |
? originalDescriptor.get.call(compRef.instance) | |
: routerData; | |
}, | |
set(value: any) { | |
routerData = value; | |
if (originalDescriptor) originalDescriptor.set.call(compRef.instance, routerData); | |
} | |
}; | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment