Merge pull request #1437 from dpalou/MOBILE-2538
MOBILE-2538 splitview: Handle ionViewCanLeave in details pagesmain
commit
00c6a3aef2
|
@ -14,8 +14,9 @@
|
|||
|
||||
// Code based on https://github.com/martinpritchardelevate/ionic-split-pane-demo
|
||||
|
||||
import { Component, ViewChild, Input, ElementRef, OnInit, Optional } from '@angular/core';
|
||||
import { NavController, Nav } from 'ionic-angular';
|
||||
import { Component, ViewChild, Input, ElementRef, OnInit, Optional, OnDestroy } from '@angular/core';
|
||||
import { NavController, Nav, ViewController } from 'ionic-angular';
|
||||
import { Subscription } from 'rxjs';
|
||||
|
||||
/**
|
||||
* Directive to create a split view layout.
|
||||
|
@ -40,7 +41,7 @@ import { NavController, Nav } from 'ionic-angular';
|
|||
selector: 'core-split-view',
|
||||
templateUrl: 'core-split-view.html'
|
||||
})
|
||||
export class CoreSplitViewComponent implements OnInit {
|
||||
export class CoreSplitViewComponent implements OnInit, OnDestroy {
|
||||
|
||||
@ViewChild('detailNav') detailNav: Nav;
|
||||
@Input() when?: string | boolean = 'md';
|
||||
|
@ -49,6 +50,9 @@ export class CoreSplitViewComponent implements OnInit {
|
|||
protected masterPageIndex = 0;
|
||||
protected loadDetailPage: any = false;
|
||||
protected element: HTMLElement; // Current element.
|
||||
protected detailsDidEnterSubscription: Subscription;
|
||||
protected masterCanLeaveOverridden = false;
|
||||
protected originalMasterCanLeave: Function;
|
||||
|
||||
// Empty placeholder for the 'detail' page.
|
||||
detailPage: any = null;
|
||||
|
@ -65,6 +69,8 @@ export class CoreSplitViewComponent implements OnInit {
|
|||
this.masterPageName = this.masterNav.getActive().component.name;
|
||||
this.masterPageIndex = this.masterNav.indexOf(this.masterNav.getActive());
|
||||
this.emptyDetails();
|
||||
|
||||
this.handleCanLeave();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -89,6 +95,54 @@ export class CoreSplitViewComponent implements OnInit {
|
|||
return this.masterNav;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle ionViewCanLeave functions in details page. By default, this function isn't captured by Ionic when
|
||||
* clicking the back button, it only uses the one in the master page.
|
||||
*/
|
||||
handleCanLeave(): void {
|
||||
// Listen for the didEnter event on the details nav to detect everytime a page is loaded.
|
||||
this.detailsDidEnterSubscription = this.detailNav.viewDidEnter.subscribe((detailsViewController: ViewController) => {
|
||||
const masterViewController = this.masterNav.getActive();
|
||||
|
||||
if (this.masterCanLeaveOverridden) {
|
||||
// We've overridden the can leave of the master page for a previous details page. Restore it.
|
||||
masterViewController.instance.ionViewCanLeave = this.originalMasterCanLeave;
|
||||
this.originalMasterCanLeave = undefined;
|
||||
this.masterCanLeaveOverridden = false;
|
||||
}
|
||||
|
||||
if (detailsViewController && detailsViewController.instance && detailsViewController.instance.ionViewCanLeave) {
|
||||
// The details page defines a canLeave function. Check if the master page also defines one.
|
||||
if (masterViewController.instance.ionViewCanLeave) {
|
||||
// Master page also defines a canLeave function, store it because it will be overridden.
|
||||
this.originalMasterCanLeave = masterViewController.instance.ionViewCanLeave;
|
||||
}
|
||||
|
||||
// Override the master canLeave function so it also calls the details canLeave.
|
||||
this.masterCanLeaveOverridden = true;
|
||||
|
||||
masterViewController.instance.ionViewCanLeave = (): Promise<any> => {
|
||||
// Always return a Promise.
|
||||
return Promise.resolve().then(() => {
|
||||
if (this.originalMasterCanLeave) {
|
||||
// First call the master canLeave.
|
||||
const result = this.originalMasterCanLeave();
|
||||
if (typeof result == 'boolean' && !result) {
|
||||
// User cannot leave, return a rejected promise so the details canLeave isn't executed.
|
||||
return Promise.reject(null);
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}).then(() => {
|
||||
// User can leave the master page. Check if he can also leave the details page.
|
||||
return detailsViewController.instance.ionViewCanLeave();
|
||||
});
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if both panels are shown. It depends on screen width.
|
||||
*
|
||||
|
@ -168,4 +222,11 @@ export class CoreSplitViewComponent implements OnInit {
|
|||
this.masterNav.insert(this.masterPageIndex + 1, detailView.component, detailView.data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Component being destroyed.
|
||||
*/
|
||||
ngOnDestroy(): void {
|
||||
this.detailsDidEnterSubscription && this.detailsDidEnterSubscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue