Skip to content

Commit 566896d

Browse files
ADjenkovADjenkov
ADjenkov
authored and
ADjenkov
committed
fix(location-strategy): extend support for nested primary outlets
1 parent a51b59c commit 566896d

File tree

4 files changed

+44
-28
lines changed

4 files changed

+44
-28
lines changed

Diff for: nativescript-angular/router/ns-location-strategy.ts

+31-12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Injectable } from "@angular/core";
22
import { LocationStrategy } from "@angular/common";
3-
import { DefaultUrlSerializer, UrlSegmentGroup, UrlTree } from "@angular/router";
3+
import { DefaultUrlSerializer, UrlSegmentGroup, UrlTree, ActivatedRouteSnapshot } from "@angular/router";
44
import { routerLog, routerError, isLogEnabled } from "../trace";
55
import { NavigationTransition, Frame } from "tns-core-modules/ui/frame";
66
import { isPresent } from "../lang-facade";
@@ -88,6 +88,7 @@ export interface LocationState {
8888
segmentGroup: UrlSegmentGroup;
8989
isRootSegmentGroup: boolean;
9090
isPageNavigation: boolean;
91+
frame?: Frame;
9192
}
9293

9394
@Injectable()
@@ -162,7 +163,7 @@ export class NSLocationStrategy extends LocationStrategy {
162163
if (!Object.keys(urlTreeRoot.children).length) {
163164
const segmentGroup = this.currentUrlTree && this.currentUrlTree.root;
164165
const outletKey = this.getOutletKey(this.getSegmentGroupFullPath(segmentGroup), "primary");
165-
const outlet = this.findOutletByKey(outletKey);
166+
const outlet = this.findOutlet(outletKey);
166167

167168
if (outlet && this.updateStates(outlet, segmentGroup)) {
168169
this.currentOutlet = outlet; // If states updated
@@ -186,12 +187,12 @@ export class NSLocationStrategy extends LocationStrategy {
186187

187188
const outletPath = this.getSegmentGroupFullPath(currentTree);
188189
let outletKey = this.getOutletKey(outletPath, outletName);
189-
let outlet = this.findOutletByKey(outletKey);
190+
let outlet = this.findOutlet(outletKey);
190191

191192
const parentOutletName = currentTree.outlet || "";
192193
const parentOutletPath = this.getSegmentGroupFullPath(currentTree.parent);
193194
const parentOutletKey = this.getOutletKey(parentOutletPath, parentOutletName);
194-
const parentOutlet = this.findOutletByKey(parentOutletKey);
195+
const parentOutlet = this.findOutlet(parentOutletKey);
195196

196197
const containsLastState = outlet && outlet.containsTopState(currentSegmentGroup.toString());
197198
if (!outlet) {
@@ -237,7 +238,7 @@ export class NSLocationStrategy extends LocationStrategy {
237238
throw new Error("NSLocationStrategy.forward() - not implemented");
238239
}
239240

240-
back(outlet?: Outlet): void {
241+
back(outlet?: Outlet, frame?: Frame): void {
241242
this.currentOutlet = outlet || this.currentOutlet;
242243

243244
if (this.currentOutlet.isPageNavigationBack) {
@@ -247,6 +248,13 @@ export class NSLocationStrategy extends LocationStrategy {
247248
let state = states.pop();
248249
let count = 1;
249250

251+
if (frame) {
252+
while (state.frame !== frame) {
253+
state = states.pop();
254+
count++;
255+
}
256+
}
257+
250258
while (!state.isPageNavigation) {
251259
state = states.pop();
252260
count++;
@@ -447,9 +455,15 @@ export class NSLocationStrategy extends LocationStrategy {
447455
return this.outlets;
448456
}
449457

450-
updateOutletFrame(outlet: Outlet, frame: Frame) {
458+
updateOutletFrame(outlet: Outlet, frame: Frame, isEmptyOutletFrame: boolean) {
459+
const lastState = outlet.peekState();
460+
461+
if (lastState && !lastState.frame && !isEmptyOutletFrame) {
462+
lastState.frame = frame;
463+
}
464+
451465
if (!outlet.containsFrame(frame)) {
452-
outlet.frames.push(frame);
466+
outlet.frames.push(frame);
453467
}
454468
this.currentOutlet = outlet;
455469
}
@@ -547,12 +561,17 @@ export class NSLocationStrategy extends LocationStrategy {
547561
});
548562
}
549563

550-
findOutletByOutletPath(pathByOutlets: string): Outlet {
551-
return this.outlets.find((outlet) => outlet.pathByOutlets === pathByOutlets);
552-
}
564+
findOutlet(outletKey: string, activatedRouteSnapshot?: ActivatedRouteSnapshot): Outlet {
565+
let outlet: Outlet = this.outlets.find((currentOutlet) => currentOutlet.outletKeys.indexOf(outletKey) > -1);
553566

554-
findOutletByKey(outletKey: string): Outlet {
555-
return this.outlets.find((outlet) => outlet.outletKeys.indexOf(outletKey) > -1);
567+
// No Outlet with the given outletKey could happen when using nested unnamed p-r-o
568+
// primary -> primary -> prymary
569+
if (!outlet && activatedRouteSnapshot) {
570+
const pathByOutlets = this.getPathByOutlets(activatedRouteSnapshot);
571+
outlet = this.outlets.find((currentOutlet) => currentOutlet.pathByOutlets === pathByOutlets);
572+
}
573+
574+
return outlet;
556575
}
557576

558577
private getOutletByFrame(frame: Frame): Outlet {

Diff for: nativescript-angular/router/ns-route-reuse-strategy.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ export class NSRouteReuseStrategy implements RouteReuseStrategy {
100100
route = findTopActivatedRouteNodeForOutlet(route);
101101

102102
const outletKey = this.location.getRouteFullPath(route);
103-
const outlet = this.location.findOutletByKey(outletKey);
103+
const outlet = this.location.findOutlet(outletKey, route);
104104
const key = getSnapshotKey(route);
105105
const isPageActivated = route[pageRouterActivatedSymbol];
106106
const isBack = outlet ? outlet.isPageNavigationBack : false;
@@ -125,7 +125,7 @@ export class NSRouteReuseStrategy implements RouteReuseStrategy {
125125
route = findTopActivatedRouteNodeForOutlet(route);
126126

127127
const outletKey = this.location.getRouteFullPath(route);
128-
const outlet = this.location.findOutletByKey(outletKey);
128+
const outlet = this.location.findOutlet(outletKey, route);
129129
const cache = this.cacheByOutlet[outletKey];
130130
if (!cache) {
131131
return false;
@@ -185,7 +185,7 @@ export class NSRouteReuseStrategy implements RouteReuseStrategy {
185185
route = findTopActivatedRouteNodeForOutlet(route);
186186

187187
const outletKey = this.location.getRouteFullPath(route);
188-
const outlet = this.location.findOutletByKey(outletKey);
188+
const outlet = this.location.findOutlet(outletKey, route);
189189
const cache = this.cacheByOutlet[outletKey];
190190
if (!cache) {
191191
return null;

Diff for: nativescript-angular/router/page-router-outlet.ts

+9-12
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ export class PageRouterOutlet implements OnDestroy { // tslint:disable-line:dire
287287
}
288288

289289
this.outlet.isNSEmptyOutlet = this.isEmptyOutlet;
290-
this.locationStrategy.updateOutletFrame(this.outlet, this.frame);
290+
this.locationStrategy.updateOutletFrame(this.outlet, this.frame, this.isEmptyOutlet);
291291

292292
if (this.outlet && this.outlet.isPageNavigationBack) {
293293
if (isLogEnabled()) {
@@ -355,7 +355,7 @@ export class PageRouterOutlet implements OnDestroy { // tslint:disable-line:dire
355355
page.on(Page.navigatedFromEvent, (<any>global).Zone.current.wrap((args: NavigatedData) => {
356356
if (args.isBackNavigation) {
357357
this.locationStrategy._beginBackPageNavigation(this.frame);
358-
this.locationStrategy.back();
358+
this.locationStrategy.back(null, this.frame);
359359
}
360360
}));
361361

@@ -394,14 +394,14 @@ export class PageRouterOutlet implements OnDestroy { // tslint:disable-line:dire
394394
queue.push(childRoute);
395395
});
396396

397-
const nodeToMark = findTopActivatedRouteNodeForOutlet(currentRoute);
398-
let outletKeyForRoute = this.locationStrategy.getRouteFullPath(nodeToMark);
399-
let outlet = this.locationStrategy.findOutletByKey(outletKeyForRoute);
397+
const topActivatedRoute = findTopActivatedRouteNodeForOutlet(currentRoute);
398+
let outletKey = this.locationStrategy.getRouteFullPath(topActivatedRoute);
399+
let outlet = this.locationStrategy.findOutlet(outletKey, topActivatedRoute);
400400

401401
if (outlet && outlet.frames.length) {
402-
nodeToMark[pageRouterActivatedSymbol] = true;
402+
topActivatedRoute[pageRouterActivatedSymbol] = true;
403403
if (isLogEnabled()) {
404-
log("Activated route marked as page: " + routeToString(nodeToMark));
404+
log("Activated route marked as page: " + routeToString(topActivatedRoute));
405405
}
406406
}
407407

@@ -429,20 +429,17 @@ export class PageRouterOutlet implements OnDestroy { // tslint:disable-line:dire
429429
if (modalNavigation > 0) { // Modal with 'primary' p-r-o
430430
outlet = this.locationStrategy.findOutletByModal(modalNavigation);
431431
} else {
432-
outlet = this.locationStrategy.findOutletByKey(outletKey);
432+
outlet = this.locationStrategy.findOutlet(outletKey, topActivatedRoute);
433433
}
434434

435435
// Named lazy loaded outlet.
436436
if (!outlet && this.isEmptyOutlet) {
437437
const parentOutletKey = this.locationStrategy.getRouteFullPath(topActivatedRoute.parent);
438-
outlet = this.locationStrategy.findOutletByKey(parentOutletKey);
438+
outlet = this.locationStrategy.findOutlet(parentOutletKey, topActivatedRoute.parent);
439439

440440
if (outlet) {
441441
outlet.outletKeys.push(outletKey);
442442
}
443-
} else if (!outlet) {
444-
const pathByOutlets = this.locationStrategy.getPathByOutlets(topActivatedRoute);
445-
outlet = this.locationStrategy.findOutletByOutletPath(pathByOutlets);
446443
}
447444

448445
return outlet;

Diff for: nativescript-angular/router/router-extensions.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ export class RouterExtensions {
126126

127127
const currentRouteSnapshop = findTopActivatedRouteNodeForOutlet(currentRoute.snapshot);
128128
const outletKey = this.locationStrategy.getRouteFullPath(currentRouteSnapshop);
129-
outlet = this.locationStrategy.findOutletByKey(outletKey);
129+
outlet = this.locationStrategy.findOutlet(outletKey, currentRouteSnapshop);
130130

131131
return outlet;
132132
}

0 commit comments

Comments
 (0)