Skip to content

Commit 596daec

Browse files
authored
Merge branch 'master' into fix/ns-views-not-cleaned-on-removal
2 parents b9b55b6 + 9b3a3ba commit 596daec

File tree

9 files changed

+107
-39
lines changed

9 files changed

+107
-39
lines changed

Diff for: e2e/single-page/app/app.css

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
.title {
2-
font-size: 30;
2+
font-size: 15;
33
margin: 16;
44
}
55

Diff for: e2e/single-page/app/app.module.ts

+5
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,19 @@ import { AppComponent } from "./app.component";
1111

1212
import { rendererTraceCategory, viewUtilCategory, routeReuseStrategyTraceCategory, routerTraceCategory } from "nativescript-angular/trace";
1313
import { setCategories, enable } from "tns-core-modules/trace";
14+
import { ModalComponent } from "./second/modal/modal.component";
1415
setCategories(routerTraceCategory + "," + routeReuseStrategyTraceCategory);
1516
enable();
1617

1718
@NgModule({
1819
declarations: [
1920
AppComponent,
21+
ModalComponent,
2022
...navigatableComponents,
2123
],
24+
entryComponents:[
25+
ModalComponent
26+
],
2227
bootstrap: [AppComponent],
2328
providers: [
2429
{ provide: NgModuleFactoryLoader, useClass: NSModuleFactoryLoader }
+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<StackLayout>
2+
<Label text="Welcome to modal"></Label>
3+
<Button text="Close Modal" (tap)="close()"></Button>
4+
</StackLayout>

Diff for: e2e/single-page/app/second/modal/modal.component.ts

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { Component } from '@angular/core';
2+
import { ModalDialogParams } from "nativescript-angular/modal-dialog";
3+
4+
@Component({
5+
moduleId: module.id,
6+
selector: 'modal',
7+
templateUrl: './modal.component.html'
8+
})
9+
10+
export class ModalComponent {
11+
12+
constructor(private params: ModalDialogParams) {
13+
}
14+
15+
public close() {
16+
this.params.closeCallback();
17+
}
18+
19+
}

Diff for: e2e/single-page/app/second/second.component.ts

+20-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
import { Component, OnInit, OnDestroy } from "@angular/core";
1+
import { Component, OnInit, OnDestroy, ViewContainerRef } from "@angular/core";
22
import { ActivatedRoute, Router, Route } from "@angular/router";
33

4+
import { ModalDialogService, ModalDialogOptions } from "nativescript-angular";
45
import { Page } from "tns-core-modules/ui/page";
56
import { Observable } from "rxjs";
67
import { map } from "rxjs/operators";
78
import { RouterExtensions } from "nativescript-angular/router";
9+
import { ModalComponent } from "./modal/modal.component";
810

911
@Component({
1012
selector: "second",
@@ -19,12 +21,16 @@ import { RouterExtensions } from "nativescript-angular/router";
1921
2022
<StackLayout>
2123
<Label [text]="'Second Component: ' + (id$ | async)" class="title"></Label>
24+
<Button text="Show Modal" (tap)="onShowModal()"></Button>
2225
<Button text="Back" (tap)="back()"></Button>
2326
</StackLayout>`
2427
})
2528
export class SecondComponent implements OnInit, OnDestroy {
2629
public id$: Observable<number>;
27-
constructor(route: ActivatedRoute, private routerExtensions: RouterExtensions) {
30+
constructor(route: ActivatedRoute,
31+
private routerExtensions: RouterExtensions,
32+
private viewContainerRef: ViewContainerRef,
33+
private modalService: ModalDialogService) {
2834
this.id$ = route.params.pipe(map(r => +r["id"]));
2935
}
3036

@@ -39,4 +45,16 @@ export class SecondComponent implements OnInit, OnDestroy {
3945
back() {
4046
this.routerExtensions.back();
4147
}
48+
49+
onShowModal() {
50+
let options: ModalDialogOptions = {
51+
viewContainerRef: this.viewContainerRef,
52+
context: {
53+
},
54+
fullscreen: true
55+
};
56+
57+
this.modalService.showModal(ModalComponent, options).then((dialogResult: string) => {
58+
});
59+
}
4260
}

Diff for: e2e/single-page/e2e/tests.e2e-spec.ts

+24-8
Original file line numberDiff line numberDiff line change
@@ -19,29 +19,45 @@ describe("Single page app", () => {
1919
});
2020

2121
it("should load second(1) page", async () => {
22-
await findAndClick(driver, "SECOND(1)")
22+
await findAndClick(driver, "SECOND(1)");
2323

2424
await driver.findElementByAutomationText("Second Component: 1");
25-
25+
2626
// ActionBar Title and item
2727
await driver.findElementByAutomationText("Second Title");
2828
await driver.findElementByAutomationText("ACTION2");
2929
});
3030

3131
it("should load second(2) page", async () => {
32-
await findAndClick(driver, "SECOND(2)")
32+
await findAndClick(driver, "SECOND(2)");
33+
34+
await driver.findElementByAutomationText("Second Component: 2");
3335

34-
await driver.findElementByAutomationText("Second Component: 1");
35-
3636
// ActionBar Title and items
3737
await driver.findElementByAutomationText("Second Title");
3838
await driver.findElementByAutomationText("ACTION2");
3939
await driver.findElementByAutomationText("ADD");
4040
});
41+
42+
it("should open and close modal view", async () => {
43+
await findAndClick(driver, "Show Modal");
44+
45+
await driver.findElementByAutomationText("Welcome to modal");
46+
await findAndClick(driver, "Close Modal");
47+
48+
await driver.findElementByAutomationText("Second Component: 2");
49+
});
50+
51+
it("should go back to second(1) and first", async () => {
52+
await findAndClick(driver, "Back");
53+
await driver.findElementByAutomationText("Second Component: 1");
54+
await findAndClick(driver, "Back");
55+
await driver.findElementByAutomationText("First Title");
56+
await driver.findElementByAutomationText("ACTION1");
57+
});
4158
});
4259

4360
async function findAndClick(driver: AppiumDriver, text: string) {
44-
const navigationButton =
45-
await driver.findElementByAutomationText(text);
46-
navigationButton.click();
61+
const navigationButton = await driver.findElementByAutomationText(text);
62+
await navigationButton.click();
4763
}

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

+1-3
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,7 @@ export class ModalDialogService {
8787
frame = (parentView.page && parentView.page.frame) || topmost();
8888
}
8989

90-
if (frame) {
91-
this.location._beginModalNavigation(frame);
92-
}
90+
this.location._beginModalNavigation(frame);
9391

9492
return new Promise((resolve, reject) => {
9593
setTimeout(() => {

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

+32-17
Original file line numberDiff line numberDiff line change
@@ -275,9 +275,13 @@ export class NSLocationStrategy extends LocationStrategy {
275275

276276
if (!outlet) {
277277
const topmostFrame = this.frameService.getFrame();
278-
this.currentOutlet = this.getOutletByFrame(topmostFrame);
278+
this.currentOutlet = this.getOutletByFrame(topmostFrame) || this.currentOutlet;
279+
}
280+
281+
const frameToBack: Frame = this.currentOutlet.getFrameToBack();
282+
if (frameToBack) {
283+
frameToBack.goBack();
279284
}
280-
this.currentOutlet.getFrameToBack().goBack();
281285
} else {
282286
// Nested navigation - just pop the state
283287
if (isLogEnabled()) {
@@ -385,10 +389,11 @@ export class NSLocationStrategy extends LocationStrategy {
385389
routerLog("NSLocationStrategy._beginModalNavigation()");
386390
}
387391

388-
this.currentOutlet = this.getOutletByFrame(frame);
392+
this.currentOutlet = this.getOutletByFrame(frame) || this.currentOutlet;
389393

390394
// It is possible to have frame, but not corresponding Outlet, if
391-
// showing modal dialog on app.component.ts ngOnInit() e.g.
395+
// showing modal dialog on app.component.ts ngOnInit() e.g. In that case
396+
// the modal is treated as none modal navigation.
392397
if (this.currentOutlet) {
393398
this.currentOutlet.showingModal = true;
394399
this._modalNavigationDepth++;
@@ -400,15 +405,18 @@ export class NSLocationStrategy extends LocationStrategy {
400405
routerLog("NSLocationStrategy.closeModalNavigation()");
401406
}
402407

403-
if (this._modalNavigationDepth > 0) {
408+
const isShowingModal = this._modalNavigationDepth > 0;
409+
410+
if (isShowingModal) {
404411
this._modalNavigationDepth--;
405412
}
406413

407414
// currentOutlet should be the one that corresponds to the topmost() frame
408415
const topmostOutlet = this.getOutletByFrame(this.frameService.getFrame());
409-
this.currentOutlet = this.findOutletByModal(this._modalNavigationDepth, true) || topmostOutlet;
416+
const outlet = this.findOutletByModal(this._modalNavigationDepth, isShowingModal) || topmostOutlet;
410417

411-
if (this.currentOutlet) {
418+
if (outlet) {
419+
this.currentOutlet = outlet;
412420
this.currentOutlet.showingModal = false;
413421
this.callPopState(this.currentOutlet.peekState(), false);
414422
}
@@ -481,7 +489,8 @@ export class NSLocationStrategy extends LocationStrategy {
481489
this.callPopState(null, true, currentOutlet);
482490
}
483491

484-
if (!currentOutlet.isNSEmptyOutlet) {
492+
// Skip frames filtering since currentOutlet is <router-outlet> when no frames available.
493+
if (currentOutlet.frames.length && !currentOutlet.isNSEmptyOutlet) {
485494
currentOutlet.frames = currentOutlet.frames.filter(currentFrame => currentFrame !== frame);
486495
return currentOutlet.frames.length;
487496
}
@@ -554,26 +563,32 @@ export class NSLocationStrategy extends LocationStrategy {
554563
return pathToOutlet || lastPath;
555564
}
556565

557-
findOutletByModal(modalNavigation: number, isShowingModal?: boolean): Outlet {
558-
return this.outlets.find((outlet) => {
559-
let isEqual = outlet.modalNavigationDepth === modalNavigation;
560-
return isShowingModal ? isEqual && outlet.showingModal : isEqual;
561-
});
562-
}
563-
564566
findOutlet(outletKey: string, activatedRouteSnapshot?: ActivatedRouteSnapshot): Outlet {
565-
let outlet: Outlet = this.outlets.find((currentOutlet) => currentOutlet.outletKeys.indexOf(outletKey) > -1);
567+
let outlet: Outlet = this.outlets.find((currentOutlet) => {
568+
let equalModalDepth = currentOutlet.modalNavigationDepth === this._modalNavigationDepth;
569+
return equalModalDepth && currentOutlet.outletKeys.indexOf(outletKey) > -1;
570+
});
566571

567572
// No Outlet with the given outletKey could happen when using nested unnamed p-r-o
568573
// primary -> primary -> prymary
569574
if (!outlet && activatedRouteSnapshot) {
570575
const pathByOutlets = this.getPathByOutlets(activatedRouteSnapshot);
571-
outlet = this.outlets.find((currentOutlet) => currentOutlet.pathByOutlets === pathByOutlets);
576+
outlet = this.outlets.find((currentOutlet) => {
577+
let equalModalDepth = currentOutlet.modalNavigationDepth === this._modalNavigationDepth;
578+
return equalModalDepth && currentOutlet.pathByOutlets === pathByOutlets;
579+
});
572580
}
573581

574582
return outlet;
575583
}
576584

585+
private findOutletByModal(modalNavigation: number, isShowingModal?: boolean): Outlet {
586+
return this.outlets.find((outlet) => {
587+
let equalModalDepth = outlet.modalNavigationDepth === modalNavigation;
588+
return isShowingModal ? equalModalDepth && outlet.showingModal : equalModalDepth;
589+
});
590+
}
591+
577592
private getOutletByFrame(frame: Frame): Outlet {
578593
let outlet;
579594

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

+1-8
Original file line numberDiff line numberDiff line change
@@ -431,15 +431,8 @@ export class PageRouterOutlet implements OnDestroy { // tslint:disable-line:dire
431431

432432
private getOutlet(activatedRouteSnapshot: ActivatedRouteSnapshot): Outlet {
433433
const topActivatedRoute = findTopActivatedRouteNodeForOutlet(activatedRouteSnapshot);
434-
const modalNavigation = this.locationStrategy._modalNavigationDepth;
435434
const outletKey = this.locationStrategy.getRouteFullPath(topActivatedRoute);
436-
let outlet;
437-
438-
if (modalNavigation > 0) { // Modal with 'primary' p-r-o
439-
outlet = this.locationStrategy.findOutletByModal(modalNavigation);
440-
} else {
441-
outlet = this.locationStrategy.findOutlet(outletKey, topActivatedRoute);
442-
}
435+
let outlet = this.locationStrategy.findOutlet(outletKey, topActivatedRoute);
443436

444437
// Named lazy loaded outlet.
445438
if (!outlet && this.isEmptyOutlet) {

0 commit comments

Comments
 (0)