Skip to content

Commit e9ce80c

Browse files
committed
fix: mark cache for clearing for better consistency
1 parent 82625d3 commit e9ce80c

File tree

2 files changed

+54
-2
lines changed

2 files changed

+54
-2
lines changed

packages/angular/src/lib/legacy/router/ns-route-reuse-strategy.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ interface CacheItem {
99
key: string;
1010
state: DetachedRouteHandle;
1111
isModal: boolean;
12+
markedForDeletion?: boolean;
1213
}
1314

1415
const getSnapshotKey = function (snapshot: ActivatedRouteSnapshot): string {
@@ -52,6 +53,28 @@ class DetachedStateCache {
5253
}
5354
}
5455

56+
public markCurrentForClear() {
57+
for (const item of this.cache) {
58+
item.markedForDeletion = true;
59+
}
60+
}
61+
62+
public clearMarked() {
63+
// try to preserve same order as .clear()
64+
for (let i = this.cache.length - 1; i >= 0; i--) {
65+
const cacheItem = this.cache[i];
66+
if (cacheItem.markedForDeletion) {
67+
const state = <any>cacheItem.state;
68+
if (!state.componentRef) {
69+
throw new Error('No componentRef found in DetachedRouteHandle');
70+
}
71+
72+
destroyComponentRef(state.componentRef);
73+
this.cache.splice(i, 1);
74+
}
75+
}
76+
}
77+
5578
public clearModalCache() {
5679
let removedItemsCount = 0;
5780
const hasModalPages = this.cache.some((cacheItem) => {
@@ -259,6 +282,14 @@ export class NSRouteReuseStrategy implements RouteReuseStrategy {
259282
}
260283
}
261284

285+
markCacheForClear(outletKey: string) {
286+
const cache = this.cacheByOutlet[outletKey];
287+
288+
if (cache) {
289+
cache.markCurrentForClear();
290+
}
291+
}
292+
262293
popCache(outletKey: string) {
263294
const cache = this.cacheByOutlet[outletKey];
264295

@@ -272,6 +303,25 @@ export class NSRouteReuseStrategy implements RouteReuseStrategy {
272303
}
273304
}
274305

306+
markCacheForPop(outletKey: string) {
307+
const cache = this.cacheByOutlet[outletKey];
308+
309+
if (cache) {
310+
const item = cache.peek();
311+
if (item) {
312+
item.markedForDeletion = true;
313+
}
314+
}
315+
}
316+
317+
clearMarkedCache(outletKey: string) {
318+
const cache = this.cacheByOutlet[outletKey];
319+
320+
if (cache) {
321+
cache.clearMarked();
322+
}
323+
}
324+
275325
clearModalCache(outletKey: string) {
276326
const cache = this.cacheByOutlet[outletKey];
277327

packages/angular/src/lib/legacy/router/page-router-outlet.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,7 @@ export class PageRouterOutlet implements OnDestroy, RouterOutletContract {
434434
const currentRoute = this.activatedRoute;
435435
// Clear refCache if navigation with clearHistory
436436
if (navOptions.clearHistory) {
437+
this.outlet.outletKeys.forEach((key) => this.routeReuseStrategy.markCacheForClear(key));
437438
const wipeCache = callableOnce(() => {
438439
if (this.postNavFunction === wipeCache) {
439440
this.postNavFunction = null;
@@ -442,7 +443,7 @@ export class PageRouterOutlet implements OnDestroy, RouterOutletContract {
442443
// potential alternative fix (only fix children of the current outlet)
443444
// const nests = outletKey.split('/');
444445
// this.outlet.outletKeys.filter((k) => k.split('/').length >= nests.length).forEach((key) => this.routeReuseStrategy.clearCache(key));
445-
this.outlet.outletKeys.forEach((key) => this.routeReuseStrategy.clearCache(key));
446+
this.outlet.outletKeys.forEach((key) => this.routeReuseStrategy.clearMarkedCache(key));
446447
}
447448
});
448449
this.postNavFunction = wipeCache;
@@ -453,6 +454,7 @@ export class PageRouterOutlet implements OnDestroy, RouterOutletContract {
453454

454455
page.once(Page.navigatedToEvent, clearCallback);
455456
} else if (navOptions.replaceUrl) {
457+
this.outlet.outletKeys.forEach((key) => this.routeReuseStrategy.markCacheForPop(key));
456458
const popCache = callableOnce(() => {
457459
if (this.postNavFunction === popCache) {
458460
this.postNavFunction = null;
@@ -461,7 +463,7 @@ export class PageRouterOutlet implements OnDestroy, RouterOutletContract {
461463
// potential alternative fix (only fix children of the current outlet)
462464
// const nests = outletKey.split('/');
463465
// this.outlet.outletKeys.filter((k) => k.split('/').length >= nests.length).forEach((key) => this.routeReuseStrategy.popCache(key));
464-
this.outlet.outletKeys.forEach((key) => this.routeReuseStrategy.popCache(key));
466+
this.outlet.outletKeys.forEach((key) => this.routeReuseStrategy.clearMarkedCache(key));
465467
}
466468
});
467469
this.postNavFunction = popCache;

0 commit comments

Comments
 (0)