diff --git a/angular/src/directives/navigation/ion-router-outlet.ts b/angular/src/directives/navigation/ion-router-outlet.ts index 8995de2566..f50095f177 100644 --- a/angular/src/directives/navigation/ion-router-outlet.ts +++ b/angular/src/directives/navigation/ion-router-outlet.ts @@ -162,11 +162,11 @@ export class IonRouterOutlet implements OnDestroy, OnInit { } function emitEvent(el: HTMLElement) { - const event = new CustomEvent('ionRouterOutletActivated', { + const ev = new CustomEvent('ionRouterOutletActivated', { bubbles: true, cancelable: true, }); - el.dispatchEvent(event); + el.dispatchEvent(ev); } class OutletInjector implements Injector { diff --git a/angular/src/directives/navigation/router-controller.ts b/angular/src/directives/navigation/router-controller.ts index 92eeade059..0bf121e035 100644 --- a/angular/src/directives/navigation/router-controller.ts +++ b/angular/src/directives/navigation/router-controller.ts @@ -39,7 +39,6 @@ export class StackController { const leavingView = this.getActive(); this.insertView(enteringView, direction); await this.transition(enteringView, leavingView, direction, animated, this.canGoBack(1)); - this.cleanup(); } diff --git a/angular/src/ionic-module.ts b/angular/src/ionic-module.ts index f5cdb0883c..3802659342 100644 --- a/angular/src/ionic-module.ts +++ b/angular/src/ionic-module.ts @@ -1,4 +1,5 @@ import { APP_INITIALIZER, ModuleWithProviders, NgModule } from '@angular/core'; +import { IonicConfig } from '@ionic/core'; import { CommonModule } from '@angular/common'; import { appInitialize } from './app-initialize'; @@ -133,7 +134,7 @@ const PROVIDERS = [ imports: [CommonModule] }) export class IonicModule { - static forRoot(config?: { [key: string]: any }): ModuleWithProviders { + static forRoot(config?: IonicConfig): ModuleWithProviders { return { ngModule: IonicModule, providers: [ diff --git a/angular/src/providers/config.ts b/angular/src/providers/config.ts index 2cb81fd917..2d4ec5b0a2 100644 --- a/angular/src/providers/config.ts +++ b/angular/src/providers/config.ts @@ -1,11 +1,11 @@ -import { Config as CoreConfig } from '@ionic/core'; +import { Config as CoreConfig, IonicConfig } from '@ionic/core'; import { InjectionToken } from '@angular/core'; import { IonicWindow } from '../types/interfaces'; export class Config { - get(key: string, fallback?: any): any { + get(key: keyof IonicConfig, fallback?: any): any { const c = getConfig(); if (c) { return c.get(key, fallback); @@ -13,7 +13,7 @@ export class Config { return null; } - getBoolean(key: string, fallback?: boolean): boolean { + getBoolean(key: keyof IonicConfig, fallback?: boolean): boolean { const c = getConfig(); if (c) { return c.getBoolean(key, fallback); @@ -21,7 +21,7 @@ export class Config { return false; } - getNumber(key: string, fallback?: number): number { + getNumber(key: keyof IonicConfig, fallback?: number): number { const c = getConfig(); if (c) { return c.getNumber(key, fallback); @@ -29,7 +29,7 @@ export class Config { return 0; } - set(key: string, value?: any) { + set(key: keyof IonicConfig, value?: any) { const c = getConfig(); if (c) { c.set(key, value); diff --git a/core/src/components/router-outlet/route-outlet.tsx b/core/src/components/router-outlet/route-outlet.tsx index d273c6c2ab..7add357688 100644 --- a/core/src/components/router-outlet/route-outlet.tsx +++ b/core/src/components/router-outlet/route-outlet.tsx @@ -11,9 +11,9 @@ import { attachComponent, detachComponent } from '../../utils/framework-delegate }) export class RouterOutlet implements NavOutlet { - private isTransitioning = false; private activeEl: HTMLElement | undefined; private activeComponent: any; + private waitPromise?: Promise; mode!: Mode; @@ -36,7 +36,6 @@ export class RouterOutlet implements NavOutlet { if (this.animated === undefined) { this.animated = this.config.getBoolean('animate', true); } - this.ionNavWillLoad.emit(); } @@ -49,20 +48,19 @@ export class RouterOutlet implements NavOutlet { */ @Method() async setRoot(component: ComponentRef, params?: ComponentProps, opts?: RouterOutletOptions): Promise { - if (this.isTransitioning || this.activeComponent === component) { + if (this.activeComponent === component) { return false; } - this.activeComponent = component; // attach entering view to DOM - const enteringEl = await attachComponent(this.delegate, this.el, component, ['ion-page', 'ion-page-invisible'], params); const leavingEl = this.activeEl; + const enteringEl = await attachComponent(this.delegate, this.el, component, ['ion-page', 'ion-page-invisible'], params); + + this.activeComponent = component; + this.activeEl = enteringEl; // commit animation await this.commit(enteringEl, leavingEl, opts); - - // remove leaving view - this.activeEl = enteringEl; detachComponent(this.delegate, leavingEl); return true; @@ -71,35 +69,15 @@ export class RouterOutlet implements NavOutlet { /** @hidden */ @Method() async commit(enteringEl: HTMLElement, leavingEl: HTMLElement | undefined, opts?: RouterOutletOptions): Promise { - // isTransitioning acts as a lock to prevent reentering - if (this.isTransitioning || leavingEl === enteringEl) { - return false; + const unlock = await this.lock(); + let changed = false; + try { + changed = await this.transition(enteringEl, leavingEl, opts); + } catch (e) { + console.error(e); } - this.isTransitioning = true; - - // emit nav will change event - this.ionNavWillChange.emit(); - - opts = opts || {}; - - const { mode, queue, animated, animationCtrl, win, el } = this; - await transition({ - mode, - queue, - animated, - animationCtrl, - window: win, - enteringEl, - leavingEl, - baseEl: el, - - ...opts - }); - this.isTransitioning = false; - - // emit nav changed event - this.ionNavDidChange.emit(); - return true; + unlock(); + return changed; } /** @hidden */ @@ -125,6 +103,48 @@ export class RouterOutlet implements NavOutlet { } : undefined; } + private async lock() { + const p = this.waitPromise; + let resolve!: () => void; + this.waitPromise = new Promise(r => resolve = r); + + if (p) { + await p; + } + return resolve; + } + + async transition(enteringEl: HTMLElement, leavingEl: HTMLElement | undefined, opts?: RouterOutletOptions): Promise { + // isTransitioning acts as a lock to prevent reentering + if (leavingEl === enteringEl) { + return false; + } + + // emit nav will change event + this.ionNavWillChange.emit(); + + opts = opts || {}; + + const { mode, queue, animated, animationCtrl, win, el } = this; + await transition({ + mode, + queue, + animated, + animationCtrl, + window: win, + enteringEl, + leavingEl, + baseEl: el, + + ...opts + }); + + // emit nav changed event + this.ionNavDidChange.emit(); + + return true; + } + render() { return [ this.mode === 'ios' &&