@@ -29,6 +29,17 @@ function isComponentFactoryResolver(item: any): item is ComponentFactoryResolver
29
29
return ! ! item . resolveComponentFactory ;
30
30
}
31
31
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
+
32
43
export class DestructibleInjector implements Injector {
33
44
private refs = new Set < any > ( ) ;
34
45
constructor ( private destructibleProviders : ProviderSet , private parent : Injector ) { }
@@ -79,6 +90,10 @@ export class PageRouterOutlet implements OnDestroy, RouterOutletContract {
79
90
private isEmptyOutlet : boolean ;
80
91
private viewUtil : ViewUtil ;
81
92
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 ;
82
97
83
98
attachEvents : EventEmitter < unknown > = new EventEmitter ( ) ;
84
99
detachEvents : EventEmitter < unknown > = new EventEmitter ( ) ;
@@ -217,6 +232,7 @@ export class PageRouterOutlet implements OnDestroy, RouterOutletContract {
217
232
if ( ! this . isActivated ) {
218
233
return ;
219
234
}
235
+ this . postNavFunction ?.( ) ;
220
236
221
237
const c = this . activated . instance ;
222
238
destroyComponentRef ( this . activated ) ;
@@ -242,6 +258,8 @@ export class PageRouterOutlet implements OnDestroy, RouterOutletContract {
242
258
NativeScriptDebug . routerLog ( `PageRouterOutlet.detach() - ${ routeToString ( this . _activatedRoute ) } ` ) ;
243
259
}
244
260
261
+ this . postNavFunction ?.( ) ;
262
+
245
263
// Detach from ChangeDetection
246
264
this . activated . hostView . detach ( ) ;
247
265
@@ -421,28 +439,45 @@ export class PageRouterOutlet implements OnDestroy, RouterOutletContract {
421
439
this . locationStrategy . _beginPageNavigation ( this . frame , navOptions ) ;
422
440
const isReplace = navOptions . replaceUrl && ! navOptions . clearHistory ;
423
441
442
+ const currentRoute = this . activatedRoute ;
424
443
// Clear refCache if navigation with clearHistory
425
444
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 ;
426
458
const clearCallback = ( ) =>
427
459
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 ( ) ;
434
461
} ) ;
435
462
436
463
page . once ( Page . navigatedToEvent , clearCallback ) ;
437
464
} 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 ;
438
478
const clearCallback = ( ) =>
439
479
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 ( ) ;
446
481
} ) ;
447
482
448
483
page . once ( Page . navigatedToEvent , clearCallback ) ;
0 commit comments