@@ -29,6 +29,17 @@ function isComponentFactoryResolver(item: any): item is ComponentFactoryResolver
2929 return ! ! item . resolveComponentFactory ;
3030}
3131
32+ function callableOnce < T > ( fn : ( ...args : T [ ] ) => void ) {
33+ let called = false ;
34+ return ( ...args : T [ ] ) => {
35+ if ( called ) {
36+ return ;
37+ }
38+ called = true ;
39+ return fn ( ...args ) ;
40+ } ;
41+ }
42+
3243export class DestructibleInjector implements Injector {
3344 private refs = new Set < any > ( ) ;
3445 constructor ( private destructibleProviders : ProviderSet , private parent : Injector ) { }
@@ -79,6 +90,10 @@ export class PageRouterOutlet implements OnDestroy, RouterOutletContract {
7990 private isEmptyOutlet : boolean ;
8091 private viewUtil : ViewUtil ;
8192 private frame : Frame ;
93+ // this function is used to clear the outlet cache (clear history)
94+ // usually it's cleared in `navigatedTo`, but on quick navigation, the event will be fired after angular already added more things to the cache
95+ // so now we call this if the component is detached or deactivated (meaning it's mid-navigation, before cache manipulation)
96+ private postNavFunction : ( ) => void ;
8297
8398 attachEvents : EventEmitter < unknown > = new EventEmitter ( ) ;
8499 detachEvents : EventEmitter < unknown > = new EventEmitter ( ) ;
@@ -217,6 +232,7 @@ export class PageRouterOutlet implements OnDestroy, RouterOutletContract {
217232 if ( ! this . isActivated ) {
218233 return ;
219234 }
235+ this . postNavFunction ?.( ) ;
220236
221237 const c = this . activated . instance ;
222238 destroyComponentRef ( this . activated ) ;
@@ -242,6 +258,8 @@ export class PageRouterOutlet implements OnDestroy, RouterOutletContract {
242258 NativeScriptDebug . routerLog ( `PageRouterOutlet.detach() - ${ routeToString ( this . _activatedRoute ) } ` ) ;
243259 }
244260
261+ this . postNavFunction ?.( ) ;
262+
245263 // Detach from ChangeDetection
246264 this . activated . hostView . detach ( ) ;
247265
@@ -421,28 +439,45 @@ export class PageRouterOutlet implements OnDestroy, RouterOutletContract {
421439 this . locationStrategy . _beginPageNavigation ( this . frame , navOptions ) ;
422440 const isReplace = navOptions . replaceUrl && ! navOptions . clearHistory ;
423441
442+ const currentRoute = this . activatedRoute ;
424443 // Clear refCache if navigation with clearHistory
425444 if ( navOptions . clearHistory ) {
445+ this . outlet . outletKeys . forEach ( ( key ) => this . routeReuseStrategy . markCacheForClear ( key ) ) ;
446+ const wipeCache = callableOnce ( ( ) => {
447+ if ( this . postNavFunction === wipeCache ) {
448+ this . postNavFunction = null ;
449+ }
450+ if ( this . outlet && this . activatedRoute === currentRoute ) {
451+ // potential alternative fix (only fix children of the current outlet)
452+ // const nests = outletKey.split('/');
453+ // this.outlet.outletKeys.filter((k) => k.split('/').length >= nests.length).forEach((key) => this.routeReuseStrategy.clearCache(key));
454+ this . outlet . outletKeys . forEach ( ( key ) => this . routeReuseStrategy . clearMarkedCache ( key ) ) ;
455+ }
456+ } ) ;
457+ this . postNavFunction = wipeCache ;
426458 const clearCallback = ( ) =>
427459 setTimeout ( ( ) => {
428- if ( this . outlet ) {
429- // potential alternative fix (only fix children of the current outlet)
430- // const nests = outletKey.split('/');
431- // this.outlet.outletKeys.filter((k) => k.split('/').length >= nests.length).forEach((key) => this.routeReuseStrategy.clearCache(key));
432- this . outlet . outletKeys . forEach ( ( key ) => this . routeReuseStrategy . clearCache ( key ) ) ;
433- }
460+ wipeCache ( ) ;
434461 } ) ;
435462
436463 page . once ( Page . navigatedToEvent , clearCallback ) ;
437464 } else if ( navOptions . replaceUrl ) {
465+ this . outlet . outletKeys . forEach ( ( key ) => this . routeReuseStrategy . markCacheForPop ( key ) ) ;
466+ const popCache = callableOnce ( ( ) => {
467+ if ( this . postNavFunction === popCache ) {
468+ this . postNavFunction = null ;
469+ }
470+ if ( this . outlet && this . activatedRoute === currentRoute ) {
471+ // potential alternative fix (only fix children of the current outlet)
472+ // const nests = outletKey.split('/');
473+ // this.outlet.outletKeys.filter((k) => k.split('/').length >= nests.length).forEach((key) => this.routeReuseStrategy.popCache(key));
474+ this . outlet . outletKeys . forEach ( ( key ) => this . routeReuseStrategy . clearMarkedCache ( key ) ) ;
475+ }
476+ } ) ;
477+ this . postNavFunction = popCache ;
438478 const clearCallback = ( ) =>
439479 setTimeout ( ( ) => {
440- if ( this . outlet ) {
441- // potential alternative fix (only fix children of the current outlet)
442- // const nests = outletKey.split('/');
443- // this.outlet.outletKeys.filter((k) => k.split('/').length >= nests.length).forEach((key) => this.routeReuseStrategy.popCache(key));
444- this . outlet . outletKeys . forEach ( ( key ) => this . routeReuseStrategy . popCache ( key ) ) ;
445- }
480+ popCache ( ) ;
446481 } ) ;
447482
448483 page . once ( Page . navigatedToEvent , clearCallback ) ;
0 commit comments