mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-20 12:29:55 +08:00
@ -78,20 +78,21 @@ import {ViewController} from '../nav/view-controller';
|
||||
* @demo /docs/v2/demos/action-sheet/
|
||||
* @see {@link /docs/v2/components#action-sheets ActionSheet Component Docs}
|
||||
*/
|
||||
export class ActionSheet extends ViewController {
|
||||
export class ActionSheet extends ViewController {
|
||||
|
||||
constructor(opts: ActionSheetOptions = {}) {
|
||||
opts.buttons = opts.buttons || [];
|
||||
opts.enableBackdropDismiss = isDefined(opts.enableBackdropDismiss) ? !!opts.enableBackdropDismiss : true;
|
||||
constructor(opts: ActionSheetOptions = {}) {
|
||||
opts.buttons = opts.buttons || [];
|
||||
opts.enableBackdropDismiss = isDefined(opts.enableBackdropDismiss) ? !!opts.enableBackdropDismiss : true;
|
||||
|
||||
super(ActionSheetCmp, opts);
|
||||
this.viewType = 'action-sheet';
|
||||
super(ActionSheetCmp, opts);
|
||||
this.viewType = 'action-sheet';
|
||||
this.isOverlay = true;
|
||||
|
||||
// by default, actionsheets should not fire lifecycle events of other views
|
||||
// for example, when an actionsheets enters, the current active view should
|
||||
// not fire its lifecycle events because it's not conceptually leaving
|
||||
this.fireOtherLifecycles = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
|
@ -126,6 +126,7 @@ export class Alert extends ViewController {
|
||||
|
||||
super(AlertCmp, opts);
|
||||
this.viewType = 'alert';
|
||||
this.isOverlay = true;
|
||||
|
||||
// by default, alerts should not fire lifecycle events of other views
|
||||
// for example, when an alert enters, the current active view should
|
||||
|
@ -1,4 +1,4 @@
|
||||
import {App, Page, Alert, NavController} from '../../../../../ionic/ionic';
|
||||
import {App, Page, Alert, Modal, NavController, ViewController} from '../../../../../ionic/ionic';
|
||||
|
||||
|
||||
@Page({
|
||||
@ -71,9 +71,20 @@ class E2EPage {
|
||||
let alert = Alert.create({
|
||||
title: 'Alert',
|
||||
subTitle: 'Subtitle',
|
||||
message: 'This is an alert message.',
|
||||
buttons: ['Cancel', 'Continue', 'Delete']
|
||||
message: 'This is an alert message.'
|
||||
});
|
||||
alert.addButton('Cancel');
|
||||
alert.addButton({
|
||||
text: 'Open Modal',
|
||||
handler: () => {
|
||||
let modal = Modal.create(ModalPage);
|
||||
this.nav.present(modal);
|
||||
|
||||
// do not close the alert when this button is pressed
|
||||
return false;
|
||||
}
|
||||
});
|
||||
alert.addButton('Delete');
|
||||
this.nav.present(alert);
|
||||
}
|
||||
|
||||
@ -98,6 +109,7 @@ class E2EPage {
|
||||
alert.dismiss(data);
|
||||
}, 500);
|
||||
|
||||
// do not close the alert when this button is pressed
|
||||
return false;
|
||||
}
|
||||
});
|
||||
@ -270,11 +282,33 @@ class E2EPage {
|
||||
}
|
||||
}
|
||||
|
||||
@Page({
|
||||
template: `
|
||||
<ion-toolbar>
|
||||
<ion-buttons>
|
||||
<button (click)="dismiss()">Close</button>
|
||||
</ion-buttons>
|
||||
<ion-title>Modal</ion-title>
|
||||
</ion-toolbar>
|
||||
<ion-content padding>
|
||||
Hi, I'm Bob, and I'm a modal.
|
||||
</ion-content>
|
||||
`
|
||||
})
|
||||
class ModalPage {
|
||||
constructor(private viewCtrl: ViewController) {}
|
||||
|
||||
dismiss() {
|
||||
this.viewCtrl.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@App({
|
||||
template: '<ion-nav [root]="root"></ion-nav>'
|
||||
})
|
||||
class E2EApp {
|
||||
root;
|
||||
constructor() {
|
||||
this.root = E2EPage;
|
||||
}
|
||||
|
@ -106,6 +106,7 @@ export class Modal extends ViewController {
|
||||
constructor(componentType, data={}) {
|
||||
super(componentType, data);
|
||||
this.viewType = 'modal';
|
||||
this.isOverlay = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -990,10 +990,19 @@ export class NavController extends Ion {
|
||||
} else {
|
||||
// there are no other transitions happening but this one
|
||||
// only entering/leaving should show, all others hidden
|
||||
this._views.forEach(view => {
|
||||
let shouldShow = (view === enteringView) || (view === leavingView);
|
||||
// also if a view is an overlay or the previous view is an
|
||||
// overlay then always show the overlay and the view before it
|
||||
var view: ViewController;
|
||||
var shouldShow: boolean;
|
||||
|
||||
for (var i = 0, ii = this._views.length; i < ii; i++) {
|
||||
view = this._views[i];
|
||||
shouldShow = (view === enteringView) ||
|
||||
(view === leavingView) ||
|
||||
view.isOverlay ||
|
||||
(i < ii - 1 ? this._views[i + 1].isOverlay : false);
|
||||
view.domCache(shouldShow, this._renderer);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// call each view's lifecycle events
|
||||
|
@ -477,6 +477,73 @@ export function run() {
|
||||
expect(navOptions.animate).toBe(false);
|
||||
});
|
||||
|
||||
it('should set domCache true when isAlreadyTransitioning', () => {
|
||||
let enteringView = new ViewController(Page1);
|
||||
let leavingView = new ViewController(Page2);
|
||||
let isAlreadyTransitioning = true;
|
||||
var navOptions: NavOptions = {};
|
||||
var done = () => {};
|
||||
nav._beforeTrans = () => {}; //prevent running beforeTrans for tests
|
||||
nav._renderer = null;
|
||||
|
||||
spyOn(enteringView, 'domCache');
|
||||
spyOn(leavingView, 'domCache');
|
||||
|
||||
nav._postRender(1, enteringView, leavingView, isAlreadyTransitioning, navOptions, done);
|
||||
|
||||
expect(enteringView.domCache).toHaveBeenCalledWith(true, nav._renderer);
|
||||
expect(leavingView.domCache).toHaveBeenCalledWith(true, nav._renderer);
|
||||
});
|
||||
|
||||
it('should set domCache true when isAlreadyTransitioning false for the entering/leaving views', () => {
|
||||
let view1 = new ViewController(Page1);
|
||||
let view2 = new ViewController(Page2);
|
||||
let view3 = new ViewController(Page3);
|
||||
let isAlreadyTransitioning = false;
|
||||
var navOptions: NavOptions = {};
|
||||
var done = () => {};
|
||||
nav._beforeTrans = () => {}; //prevent running beforeTrans for tests
|
||||
nav._renderer = null;
|
||||
nav._views = [view1, view2, view3];
|
||||
|
||||
spyOn(view1, 'domCache');
|
||||
spyOn(view2, 'domCache');
|
||||
spyOn(view3, 'domCache');
|
||||
|
||||
nav._postRender(1, view3, view2, isAlreadyTransitioning, navOptions, done);
|
||||
|
||||
expect(view1.domCache).toHaveBeenCalledWith(false, nav._renderer);
|
||||
expect(view2.domCache).toHaveBeenCalledWith(true, nav._renderer);
|
||||
expect(view3.domCache).toHaveBeenCalledWith(true, nav._renderer);
|
||||
});
|
||||
|
||||
it('should set domCache true when isAlreadyTransitioning false for views when a view has isOverlay=true', () => {
|
||||
let view1 = new ViewController(Page1);
|
||||
let view2 = new ViewController(Page2);
|
||||
let view3 = new ViewController(Page3);
|
||||
let view4 = new ViewController(Page4);
|
||||
let isAlreadyTransitioning = false;
|
||||
var navOptions: NavOptions = {};
|
||||
var done = () => {};
|
||||
nav._beforeTrans = () => {}; //prevent running beforeTrans for tests
|
||||
nav._renderer = null;
|
||||
nav._views = [view1, view2, view3, view4];
|
||||
|
||||
view3.isOverlay = true;
|
||||
|
||||
spyOn(view1, 'domCache');
|
||||
spyOn(view2, 'domCache');
|
||||
spyOn(view3, 'domCache');
|
||||
spyOn(view4, 'domCache');
|
||||
|
||||
nav._postRender(1, view4, view3, isAlreadyTransitioning, navOptions, done);
|
||||
|
||||
expect(view1.domCache).toHaveBeenCalledWith(false, nav._renderer);
|
||||
expect(view2.domCache).toHaveBeenCalledWith(true, nav._renderer);
|
||||
expect(view3.domCache).toHaveBeenCalledWith(true, nav._renderer);
|
||||
expect(view4.domCache).toHaveBeenCalledWith(true, nav._renderer);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('_setZIndex', () => {
|
||||
|
@ -71,6 +71,11 @@ export class ViewController {
|
||||
*/
|
||||
fireOtherLifecycles: boolean = true;
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
isOverlay: boolean = false;
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
|
Reference in New Issue
Block a user