From 766c79d2a1791cee618481ac7e007a0ee1561cb0 Mon Sep 17 00:00:00 2001 From: Manu MA Date: Mon, 21 Jan 2019 01:52:47 +0100 Subject: [PATCH] feat(angular): add global pop() (#17182) fixes #16340 --- .../navigation/ion-router-outlet.ts | 8 ++++--- .../directives/navigation/stack-controller.ts | 5 +++- angular/src/providers/nav-controller.ts | 23 +++++++++++++++++-- core/api.txt | 2 +- core/src/components.d.ts | 2 +- core/src/components/router/readme.md | 2 +- core/src/components/router/router.tsx | 4 ++-- 7 files changed, 35 insertions(+), 11 deletions(-) diff --git a/angular/src/directives/navigation/ion-router-outlet.ts b/angular/src/directives/navigation/ion-router-outlet.ts index 23e34165dd..ff9ba35e6c 100644 --- a/angular/src/directives/navigation/ion-router-outlet.ts +++ b/angular/src/directives/navigation/ion-router-outlet.ts @@ -1,4 +1,4 @@ -import { Attribute, ChangeDetectorRef, ComponentFactoryResolver, ComponentRef, Directive, ElementRef, EventEmitter, Injector, NgZone, OnDestroy, OnInit, Optional, Output, ViewContainerRef } from '@angular/core'; +import { Attribute, ChangeDetectorRef, ComponentFactoryResolver, ComponentRef, Directive, ElementRef, EventEmitter, Injector, NgZone, OnDestroy, OnInit, Optional, Output, SkipSelf, ViewContainerRef } from '@angular/core'; import { ActivatedRoute, ChildrenOutletContexts, OutletContext, PRIMARY_OUTLET, Router } from '@angular/router'; import { Config } from '../../providers/config'; @@ -51,11 +51,12 @@ export class IonRouterOutlet implements OnDestroy, OnInit { @Optional() @Attribute('tabs') tabs: string, private changeDetector: ChangeDetectorRef, private config: Config, - navCtrl: NavController, + private navCtrl: NavController, elementRef: ElementRef, router: Router, zone: NgZone, - activatedRoute: ActivatedRoute + activatedRoute: ActivatedRoute, + @SkipSelf() @Optional() readonly parentOutlet?: IonRouterOutlet ) { this.nativeEl = elementRef.nativeElement; this.name = name || PRIMARY_OUTLET; @@ -175,6 +176,7 @@ export class IonRouterOutlet implements OnDestroy, OnInit { this.activatedView = enteringView; this.stackCtrl.setActive(enteringView).then(data => { + this.navCtrl.setTopOutlet(this); this.activateEvents.emit(cmpRef.instance); this.stackEvents.emit(data); }); diff --git a/angular/src/directives/navigation/stack-controller.ts b/angular/src/directives/navigation/stack-controller.ts index e6d85bb7b4..6349f89db5 100644 --- a/angular/src/directives/navigation/stack-controller.ts +++ b/angular/src/directives/navigation/stack-controller.ts @@ -76,8 +76,11 @@ export class StackController { pop(deep: number, stackId = this.getActiveStackId()) { return this.zone.run(() => { const views = this.getStack(stackId); + if (views.length <= deep) { + return Promise.resolve(false); + } const view = views[views.length - deep - 1]; - return this.navCtrl.navigateBack(view.url); + return this.navCtrl.navigateBack(view.url).then(() => true); }); } diff --git a/angular/src/providers/nav-controller.ts b/angular/src/providers/nav-controller.ts index 1d0e309b6c..43390e8a08 100644 --- a/angular/src/providers/nav-controller.ts +++ b/angular/src/providers/nav-controller.ts @@ -3,6 +3,8 @@ import { Injectable, Optional } from '@angular/core'; import { NavigationExtras, NavigationStart, Router, UrlTree } from '@angular/router'; import { NavDirection, RouterDirection } from '@ionic/core'; +import { IonRouterOutlet } from '../directives/navigation/ion-router-outlet'; + import { Platform } from './platform'; export interface AnimationOptions { @@ -17,6 +19,7 @@ export interface NavigationOptions extends NavigationExtras, AnimationOptions {} }) export class NavController { + private topOutlet?: IonRouterOutlet; private direction: 'forward' | 'back' | 'root' | 'auto' = DEFAULT_DIRECTION; private animated?: NavDirection = DEFAULT_ANIMATED; private guessDirection: RouterDirection = 'forward'; @@ -41,7 +44,7 @@ export class NavController { } // Subscribe to backButton events - platform.backButton.subscribeWithPriority(0, () => this.goBack()); + platform.backButton.subscribeWithPriority(0, () => this.pop()); } navigateForward(url: string | UrlTree | any[], options: NavigationOptions = {}): Promise { @@ -67,16 +70,32 @@ export class NavController { } } - goBack(options: AnimationOptions = { animated: true, animationDirection: 'back' }) { + back(options: AnimationOptions = { animated: true, animationDirection: 'back' }) { this.setDirection('back', options.animated, options.animationDirection); return this.location.back(); } + async pop() { + let outlet = this.topOutlet; + + while (outlet) { + if (await outlet.pop()) { + break; + } else { + outlet = outlet.parentOutlet; + } + } + } + setDirection(direction: RouterDirection, animated?: boolean, animationDirection?: 'forward' | 'back') { this.direction = direction; this.animated = getAnimation(direction, animated, animationDirection); } + setTopOutlet(outlet: IonRouterOutlet) { + this.topOutlet = outlet; + } + consumeTransition() { let direction: RouterDirection = 'root'; let animation: NavDirection | undefined; diff --git a/core/api.txt b/core/api.txt index 73688f306c..49ea0a9138 100644 --- a/core/api.txt +++ b/core/api.txt @@ -864,7 +864,7 @@ ion-router-outlet,prop,animation,((Animation: Animation, baseEl: any, opts?: any ion-router,none ion-router,prop,root,string,'/',false,false ion-router,prop,useHash,boolean,true,false,false -ion-router,method,goBack,goBack() => Promise +ion-router,method,back,back() => Promise ion-router,method,push,push(url: string, direction?: RouterDirection) => Promise ion-router,event,ionRouteDidChange,RouterEventDetail,true ion-router,event,ionRouteWillChange,RouterEventDetail,true diff --git a/core/src/components.d.ts b/core/src/components.d.ts index 994dbe12be..ef52395301 100644 --- a/core/src/components.d.ts +++ b/core/src/components.d.ts @@ -3620,7 +3620,7 @@ export namespace Components { /** * Go back to previous page in the window.history. */ - 'goBack': () => Promise; + 'back': () => Promise; 'navChanged': (direction: RouterDirection) => Promise; 'printDebug': () => void; /** diff --git a/core/src/components/router/readme.md b/core/src/components/router/readme.md index fc3ffeaad6..1e4d7cae91 100644 --- a/core/src/components/router/readme.md +++ b/core/src/components/router/readme.md @@ -69,7 +69,7 @@ If you're using Angular, please see [ion-router-outlet](../router-outlet) instea ## Methods -### `goBack() => Promise` +### `back() => Promise` Go back to previous page in the window.history. diff --git a/core/src/components/router/router.tsx b/core/src/components/router/router.tsx index 2eba8ce468..c5a32bf4ec 100644 --- a/core/src/components/router/router.tsx +++ b/core/src/components/router/router.tsx @@ -83,7 +83,7 @@ export class Router implements ComponentInterface { @Listen('document:ionBackButton') protected onBackButton(ev: BackButtonEvent) { - ev.detail.register(0, () => this.goBack()); + ev.detail.register(0, () => this.back()); } /** @@ -105,7 +105,7 @@ export class Router implements ComponentInterface { * Go back to previous page in the window.history. */ @Method() - goBack() { + back() { this.win.history.back(); return Promise.resolve(this.waitPromise); }