diff --git a/angular/src/directives/navigation/stack-controller.ts b/angular/src/directives/navigation/stack-controller.ts index a63d5b4e74..a9f6be5815 100644 --- a/angular/src/directives/navigation/stack-controller.ts +++ b/angular/src/directives/navigation/stack-controller.ts @@ -43,7 +43,11 @@ export class StackController { getExistingView(activatedRoute: ActivatedRoute): RouteView | undefined { const activatedUrlKey = getUrl(this.router, activatedRoute); - return this.views.find(vw => vw.url === activatedUrlKey); + const view = this.views.find(vw => vw.url === activatedUrlKey); + if (view) { + view.ref.changeDetectorRef.reattach(); + } + return view; } async setActive(enteringView: RouteView) { @@ -55,7 +59,7 @@ export class StackController { } this.insertView(enteringView, direction); await this.transition(enteringView, leavingView, animation, this.canGoBack(1), false); - this.cleanup(); + requestAnimationFrame(() => this.cleanup()); } canGoBack(deep: number, stackId = this.getActiveStackId()): boolean { @@ -63,22 +67,27 @@ export class StackController { } pop(deep: number, stackId = this.getActiveStackId()) { - this.zone.run(() => { + return this.zone.run(() => { const views = this.getStack(stackId); const view = views[views.length - deep - 1]; - this.navCtrl.navigateBack(view.url); + return this.navCtrl.navigateBack(view.url); }); } - startBackTransition(stackId = this.getActiveStackId()) { - const views = this.getStack(stackId); - this.transition( - views[views.length - 2], // entering view - views[views.length - 1], // leaving view - 'back', - true, - true - ); + startBackTransition() { + const leavingView = this.activeView; + if (leavingView) { + const views = this.getStack(leavingView.stackId); + const enteringView = views[views.length - 2]; + enteringView.ref.changeDetectorRef.reattach(); + this.transition( + enteringView, // entering view + leavingView, // leaving view + 'back', + true, + true + ); + } } endBackTransition(shouldComplete: boolean) { @@ -125,6 +134,7 @@ export class StackController { const element = view.element; element.setAttribute('aria-hidden', 'true'); element.classList.add('ion-page-hidden'); + view.ref.changeDetectorRef.detach(); } }); this.viewsSnapshot = views.slice(); @@ -145,11 +155,6 @@ export class StackController { this.skipTransition = false; return; } - // TODO - // if (enteringView) { - // enteringView.ref.changeDetectorRef.reattach(); - // enteringView.ref.changeDetectorRef.markForCheck(); - // } const enteringEl = enteringView ? enteringView.element : undefined; const leavingEl = leavingView ? leavingView.element : undefined; const containerEl = this.containerEl; diff --git a/angular/src/providers/angular-delegate.ts b/angular/src/providers/angular-delegate.ts index 845e488c23..eceef7e5b0 100644 --- a/angular/src/providers/angular-delegate.ts +++ b/angular/src/providers/angular-delegate.ts @@ -110,6 +110,7 @@ const LIFECYCLES = [ LIFECYCLE_DID_ENTER, LIFECYCLE_WILL_LEAVE, LIFECYCLE_DID_LEAVE, + LIFECYCLE_WILL_UNLOAD ]; export function bindLifecycleEvents(instance: any, element: HTMLElement) { diff --git a/angular/test/test-app/e2e/src/router-link.e2e-spec.ts b/angular/test/test-app/e2e/src/router-link.e2e-spec.ts index 3f08185cea..5554e3df8f 100644 --- a/angular/test/test-app/e2e/src/router-link.e2e-spec.ts +++ b/angular/test/test-app/e2e/src/router-link.e2e-spec.ts @@ -25,6 +25,18 @@ describe('router-link', () => { it('should go forward with ion-button[routerLink]', async () => { await element(by.css('#routerLink')).click(); await testForward(); + + // test go back + await element(by.css('ion-back-button')).click(); + await waitTime(500); + + await testStack('ion-router-outlet', ['app-router-link']); + await testLifeCycle('app-router-link', { + ionViewWillEnter: 2, + ionViewDidEnter: 2, + ionViewWillLeave: 1, + ionViewDidLeave: 1, + }); }); it('should go forward with a[routerLink]', async () => { @@ -95,6 +107,7 @@ async function testForward() { ionViewWillLeave: 0, ionViewDidLeave: 0, }); + } async function testRoot() {