fix(angular): ensure active page is not removed from change detection (#18299)

fixes #18293
This commit is contained in:
Liam DeBeasi
2019-05-20 12:08:19 -04:00
committed by GitHub
parent bdd5109dbe
commit b8d4961483
2 changed files with 23 additions and 6 deletions

View File

@ -1,3 +1,4 @@
import { Location } from '@angular/common';
import { ComponentRef, NgZone } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { RouterDirection } from '@ionic/core';
@ -22,6 +23,7 @@ export class StackController {
private router: Router,
private navCtrl: NavController,
private zone: NgZone,
private location: Location
) {
this.tabsPrefix = tabsPrefix !== undefined ? toSegments(tabsPrefix) : undefined;
}
@ -95,7 +97,7 @@ export class StackController {
const views = this.insertView(enteringView, direction);
return this.wait(async () => {
await this.transition(enteringView, leavingView, animation, this.canGoBack(1), false);
await cleanupAsync(enteringView, views, viewsSnapshot);
await cleanupAsync(enteringView, views, viewsSnapshot, this.location);
return {
enteringView,
direction,
@ -228,22 +230,35 @@ export class StackController {
}
}
function cleanupAsync(activeRoute: RouteView, views: RouteView[], viewsSnapshot: RouteView[]) {
function cleanupAsync(activeRoute: RouteView, views: RouteView[], viewsSnapshot: RouteView[], location: Location) {
return new Promise(resolve => {
requestAnimationFrame(() => {
cleanup(activeRoute, views, viewsSnapshot);
cleanup(activeRoute, views, viewsSnapshot, location);
resolve();
});
});
}
function cleanup(activeRoute: RouteView, views: RouteView[], viewsSnapshot: RouteView[]) {
function cleanup(activeRoute: RouteView, views: RouteView[], viewsSnapshot: RouteView[], location: Location) {
viewsSnapshot
.filter(view => !views.includes(view))
.forEach(destroyView);
views.forEach(view => {
if (view !== activeRoute) {
/**
* In the event that a user navigated multiple
* times in rapid succession, we want to make sure
* we don't pre-emptively detach a view while
* it is in mid-transition.
*
* In this instance we also do not care about query
* params or fragments as it will be the same view regardless
*/
const locationWithoutParams = location.path().split('?')[0];
const locationWithoutFragment = locationWithoutParams.split('#')[0];
if (view !== activeRoute && view.url !== locationWithoutFragment) {
const element = view.element;
element.setAttribute('aria-hidden', 'true');
element.classList.add('ion-page-hidden');