Skip to content

Commit 237c733

Browse files
ADjenkovADjenkov
ADjenkov
authored and
ADjenkov
committed
fix(location-strategy): find the correct outlet when navigating back and forward
1 parent d2b3395 commit 237c733

File tree

3 files changed

+44
-16
lines changed

3 files changed

+44
-16
lines changed

Diff for: nativescript-angular/directives/dialogs.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,9 @@ export class ModalDialogService {
7474
const componentContainer = moduleRef || viewContainerRef;
7575
const resolver = componentContainer.injector.get(ComponentFactoryResolver);
7676

77-
this.location._beginModalNavigation();
77+
const frame = parentView.page && parentView.page.frame;
78+
79+
this.location._beginModalNavigation(frame);
7880

7981
return new Promise(resolve => {
8082
setTimeout(() => this._showDialog({

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

+35-12
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { Injectable } from "@angular/core";
22
import { LocationStrategy } from "@angular/common";
33
import { DefaultUrlSerializer, UrlSegmentGroup, UrlTree } from "@angular/router";
44
import { routerLog } from "../trace";
5-
import { NavigationTransition } from "tns-core-modules/ui/frame";
5+
import { NavigationTransition, Frame } from "tns-core-modules/ui/frame";
66
import { isPresent } from "../lang-facade";
77
import { FrameService } from "../platform-providers";
88

@@ -77,7 +77,7 @@ export class NSLocationStrategy extends LocationStrategy {
7777
}
7878

7979
pushState(state: any, title: string, url: string, queryParams: string): void {
80-
routerLog("NSLocationStrategy.pushState state: " +
80+
routerLog("NSLocationStrategy.pushState state: " +
8181
`${state}, title: ${title}, url: ${url}, queryParams: ${queryParams}`);
8282
this.pushStateInternal(state, title, url, queryParams);
8383
}
@@ -240,7 +240,9 @@ export class NSLocationStrategy extends LocationStrategy {
240240

241241
private callPopState(state: LocationState, pop: boolean = true) {
242242
const urlSerializer = new DefaultUrlSerializer();
243-
if (state) {
243+
const rootOutlet = this.currentUrlTree.root.children[this.currentOutlet];
244+
245+
if (state && rootOutlet) {
244246
this.currentUrlTree.root.children[this.currentOutlet] = state.segmentGroup;
245247
} else {
246248
// when closing modal view there are scenarios (e.g. root viewContainerRef) when we need
@@ -283,13 +285,20 @@ export class NSLocationStrategy extends LocationStrategy {
283285
}
284286

285287
// Methods for syncing with page navigation in PageRouterOutlet
286-
public _beginBackPageNavigation(name: string) {
288+
public _beginBackPageNavigation(name: string, frame: Frame) {
287289
routerLog("NSLocationStrategy.startGoBack()");
288290
if (this._isPageNavigationBack) {
289291
throw new Error("Calling startGoBack while going back.");
290292
}
291293
this._isPageNavigationBack = true;
292-
this.currentOutlet = name;
294+
295+
let { cachedFrame, hasDuplicateOutlet } = this.frameService.findFrame(frame, name);
296+
297+
if (cachedFrame) {
298+
this.currentOutlet = cachedFrame.rootOutlet;
299+
} else if (!hasDuplicateOutlet) {
300+
this.currentOutlet = name;
301+
}
293302
}
294303

295304
public _finishBackPageNavigation() {
@@ -304,9 +313,12 @@ export class NSLocationStrategy extends LocationStrategy {
304313
return this._isPageNavigationBack;
305314
}
306315

307-
public _beginModalNavigation(): void {
316+
public _beginModalNavigation(frame: Frame): void {
308317
routerLog("NSLocationStrategy._beginModalNavigation()");
309-
const lastState = this.peekState(this.currentOutlet);
318+
319+
let { cachedFrameRootOutlet } = this.frameService.findFrame(frame);
320+
321+
const lastState = this.peekState(cachedFrameRootOutlet || this.currentOutlet);
310322

311323
if (lastState) {
312324
lastState.isModalNavigation = true;
@@ -333,19 +345,30 @@ export class NSLocationStrategy extends LocationStrategy {
333345
this._isModalClosing = false;
334346
}
335347

336-
public _beginPageNavigation(name: string): NavigationOptions {
348+
public _beginPageNavigation(name: string, frame: Frame): NavigationOptions {
337349
routerLog("NSLocationStrategy._beginPageNavigation()");
338-
const lastState = this.peekState(name);
350+
351+
let { cachedFrame, hasDuplicateOutlet } = this.frameService.findFrame(frame, name);
352+
353+
if (cachedFrame) {
354+
this.currentOutlet = cachedFrame.rootOutlet;
355+
} else {
356+
if (!hasDuplicateOutlet) {
357+
this.currentOutlet = name;
358+
}
359+
360+
this.frameService.addFrame(frame, name, this.currentOutlet);
361+
}
362+
363+
const lastState = this.peekState(this.currentOutlet);
339364
if (lastState) {
340365
lastState.isPageNavigation = true;
341366
}
342367

343-
this.currentOutlet = name;
344-
345368
const navOptions = this._currentNavigationOptions || defaultNavOptions;
346369
if (navOptions.clearHistory) {
347370
routerLog("NSLocationStrategy._beginPageNavigation clearing states history");
348-
this.statesByOutlet[name] = [lastState];
371+
this.statesByOutlet[this.currentOutlet] = [lastState];
349372
}
350373

351374
this._currentNavigationOptions = undefined;

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

+6-3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { DetachedLoader } from "../common/detached-loader";
2525
import { ViewUtil } from "../view-util";
2626
import { NSLocationStrategy } from "./ns-location-strategy";
2727
import { NSRouteReuseStrategy } from "./ns-route-reuse-strategy";
28+
import { FrameService } from "../platform-providers";
2829

2930
export class PageRoute {
3031
activatedRoute: BehaviorSubject<ActivatedRoute>;
@@ -149,7 +150,8 @@ export class PageRouterOutlet implements OnDestroy { // tslint:disable-line:dire
149150
@Inject(DEVICE) device: Device,
150151
@Inject(PAGE_FACTORY) private pageFactory: PageFactory,
151152
private routeReuseStrategy: NSRouteReuseStrategy,
152-
elRef: ElementRef
153+
elRef: ElementRef,
154+
private frameService: FrameService
153155
) {
154156
this.frame = elRef.nativeElement;
155157
log("PageRouterOutlet.constructor frame:" + this.frame);
@@ -166,6 +168,7 @@ export class PageRouterOutlet implements OnDestroy { // tslint:disable-line:dire
166168
// destroyed on modal view closing
167169
this.routeReuseStrategy.clearModalCache(this.name);
168170
this.parentContexts.onChildOutletDestroyed(this.name);
171+
this.frameService.removeFrame(this.frame);
169172
}
170173

171174
deactivate(): void {
@@ -286,12 +289,12 @@ export class PageRouterOutlet implements OnDestroy { // tslint:disable-line:dire
286289

287290
page.on(Page.navigatedFromEvent, (<any>global).Zone.current.wrap((args: NavigatedData) => {
288291
if (args.isBackNavigation) {
289-
this.locationStrategy._beginBackPageNavigation(this.name);
292+
this.locationStrategy._beginBackPageNavigation(this.name, this.frame);
290293
this.locationStrategy.back();
291294
}
292295
}));
293296

294-
const navOptions = this.locationStrategy._beginPageNavigation(this.name);
297+
const navOptions = this.locationStrategy._beginPageNavigation(this.name, this.frame);
295298

296299
// Clear refCache if navigation with clearHistory
297300
if (navOptions.clearHistory) {

0 commit comments

Comments
 (0)