mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
wip
This commit is contained in:
@@ -1,35 +1,53 @@
|
||||
import {Injectable, Type} from 'angular2/core';
|
||||
|
||||
import {NavController, NavParams} from '../nav/nav-controller';
|
||||
import {ViewController} from '../nav/view-controller';
|
||||
import {Config} from '../../config/config';
|
||||
import {Animation} from '../../animations/animation';
|
||||
import {extend} from '../../util';
|
||||
|
||||
/**
|
||||
* @name Modal
|
||||
* @description
|
||||
* The Modal is a content pane that can go over the user's current page.
|
||||
* Usually used for making a choice or editing an item. A modal can be opened
|
||||
* similar to how {@link /docs/v2/api/components/nav/NavController/#push NavController.push} works,
|
||||
* where it is passed a Page component, along with optional Page params,
|
||||
* and options for presenting the modal.
|
||||
* Usually it is used for making a choice or editing an item. A modal uses the
|
||||
* `NavController` to "present" itself in the root nav stack. It is added to the
|
||||
* stack similar to how
|
||||
* {@link /docs/v2/api/components/nav/NavController/#push NavController.push}
|
||||
* works, where it is passed a Page component, along with optional Page params
|
||||
*
|
||||
* When a modal (or any other overlay such as an alert or actionsheet) is
|
||||
* "presented" to a nav controller, the overlay is added to the app's root nav.
|
||||
* After the modal has been presented, from within the component instance The
|
||||
* modal can later be closed or "dimsissed" by using the ViewController's
|
||||
* `dismiss` method. Additinoally, you can dismiss any overlay by using `pop`
|
||||
* on the root nav controller.
|
||||
*
|
||||
* A modal can also emit data, which is useful when it is used to add or edit
|
||||
* data. For example, a profile page could slide up in a modal, and on submit,
|
||||
* the submit button could emit the updated profile data, then dismiss the modal.
|
||||
* From that point, anything which is subscribed to the modal's `data` event
|
||||
* would receive the modal's data.
|
||||
*
|
||||
* @usage
|
||||
* ```ts
|
||||
* import {Modal, NavController} from 'ionic/ionic';
|
||||
*
|
||||
* class MyApp {
|
||||
*
|
||||
* constructor(modal: Modal) {
|
||||
* this.modal = modal;
|
||||
* constructor(nav: NavController) {
|
||||
* this.nav = nav;
|
||||
* }
|
||||
*
|
||||
* openContactModal() {
|
||||
* this.modal.open(ContactUs);
|
||||
* presentContactModal() {
|
||||
* let contactModal = Modal.create(ContactUs);
|
||||
* this.nav.present(contactModal);
|
||||
* }
|
||||
*
|
||||
* openProfileModal() {
|
||||
* this.modal.open(Profile, { userId: 8675309 }, {
|
||||
* enterAnimation: 'my-fade-in',
|
||||
* leaveAnimation: 'my-fade-out',
|
||||
* handle: 'profile-modal'
|
||||
* presentProfileModal() {
|
||||
* let profileModal = Modal.create(Profile, { userId: 8675309 });
|
||||
* this.nav.present(profileModal, {
|
||||
* animation: 'my-fade-in'
|
||||
* });
|
||||
* profileModal.data.subscribe(data => {
|
||||
* console.log(data);
|
||||
* });
|
||||
* }
|
||||
*
|
||||
@@ -38,64 +56,24 @@ import {extend} from '../../util';
|
||||
* @demo /docs/v2/demos/modal/
|
||||
* @see {@link /docs/v2/components#modals Modal Component Docs}
|
||||
*/
|
||||
@Injectable()
|
||||
export class Modal {
|
||||
export class Modal extends ViewController {
|
||||
|
||||
constructor(config: Config) {
|
||||
//this.ctrl = ctrl;
|
||||
this.config = config;
|
||||
constructor(componentType, data={}) {
|
||||
super(componentType, data);
|
||||
this.viewType = 'modal';
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a new modal using the page component is was pass as the first
|
||||
* argument. This is similar to how NavController's `push` method works.
|
||||
* Currently you must have `<ion-overlay>` in the `@App` component's template
|
||||
* for the modal to work correctly. (This is something that will
|
||||
* be hopefully be removed in the near future.)
|
||||
*
|
||||
* @param pageComponent The Page component to load in the modal.
|
||||
* @param {Object} [params={}] Optional data which can be passed to the page
|
||||
* component, which can be read from the constructor's `NavParams`.
|
||||
* @param {Object} [opts={}] Additional options for this one modal instance of.
|
||||
* Options include `enterAnimation` and `leaveAnimation`, which
|
||||
* allows customization of which animation to use.
|
||||
* @returns {Promise} Returns a promise which resolves when the modal has
|
||||
* loaded and its entering animation has completed. The resolved promise's
|
||||
* value is the instance of the newly created modal.
|
||||
*/
|
||||
open(pageComponent: Type, params={}, opts={}) {
|
||||
opts = extend({
|
||||
pageType: OVERLAY_TYPE,
|
||||
enterAnimation: this.config.get('modalEnter'),
|
||||
leaveAnimation: this.config.get('modalLeave'),
|
||||
}, opts);
|
||||
|
||||
return this.ctrl.open(pageComponent, params, opts);
|
||||
getTransitionName(direction) {
|
||||
let key = (direction === 'back' ? 'modalLeave' : 'modalEnter');
|
||||
return this._nav && this._nav.config.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the instance of a modal. This is usually helpful to getting ahold of a
|
||||
* certain modal, from anywhere within the app, and closing it. By calling
|
||||
* just `get()` without a `handle` argument, it'll return the active modal
|
||||
* on top (it is possible to have multipe modals opened at the same time).
|
||||
* If getting just the active modal isn't enough, when creating
|
||||
* a modal, it's options can be given a `handle`, which is simply a string-based
|
||||
* name for the modal instance. You can later get a reference to that modal's
|
||||
* instance by calling this method with the same handle name.
|
||||
* @param [handle] Optional string name given in the modal's options when it was opened.
|
||||
* @returns Returns the instance of the modal if it is found, otherwise `null`.
|
||||
*/
|
||||
get(handle) {
|
||||
if (handle) {
|
||||
return this.ctrl.getByHandle(handle);
|
||||
}
|
||||
return this.ctrl.getByType(OVERLAY_TYPE);
|
||||
static create(componentType, data={}) {
|
||||
return new Modal(componentType, data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const OVERLAY_TYPE = 'modal';
|
||||
|
||||
|
||||
/**
|
||||
* Animations for modals
|
||||
@@ -108,6 +86,13 @@ class ModalSlideIn extends Animation {
|
||||
.duration(400)
|
||||
.fromTo('translateY', '100%', '0%')
|
||||
.before.addClass('show-page');
|
||||
|
||||
if (enteringView.hasNavbar()) {
|
||||
// entering page has a navbar
|
||||
let enteringNavBar = new Animation(enteringView.navbarRef());
|
||||
enteringNavBar.before.addClass('show-navbar');
|
||||
this.add(enteringNavBar);
|
||||
}
|
||||
}
|
||||
}
|
||||
Animation.register('modal-slide-in', ModalSlideIn);
|
||||
@@ -134,6 +119,13 @@ class ModalMDSlideIn extends Animation {
|
||||
.fromTo('translateY', '40px', '0px')
|
||||
.fadeIn()
|
||||
.before.addClass('show-page');
|
||||
|
||||
if (enteringView.hasNavbar()) {
|
||||
// entering page has a navbar
|
||||
let enteringNavBar = new Animation(enteringView.navbarRef());
|
||||
enteringNavBar.before.addClass('show-navbar');
|
||||
this.add(enteringNavBar);
|
||||
}
|
||||
}
|
||||
}
|
||||
Animation.register('modal-md-slide-in', ModalMDSlideIn);
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
import {App, Page, Config, Platform} from 'ionic/ionic';
|
||||
import {Modal, ActionSheet, NavController, NavParams, Animation} from 'ionic/ionic';
|
||||
import {Modal, ActionSheet, NavController, NavParams, Animation, ViewController} from 'ionic/ionic';
|
||||
|
||||
|
||||
@App({
|
||||
@Page({
|
||||
templateUrl: 'main.html'
|
||||
})
|
||||
class E2EApp {
|
||||
|
||||
constructor(modal: Modal, config: Config, platform: Platform) {
|
||||
this.modal = modal;
|
||||
class E2EPage {
|
||||
|
||||
constructor(nav: NavController, config: Config, platform: Platform) {
|
||||
this.nav = nav;
|
||||
console.log('platforms', platform.platforms());
|
||||
console.log('mode', config.get('mode'));
|
||||
|
||||
@@ -29,32 +28,29 @@ class E2EApp {
|
||||
});
|
||||
}
|
||||
|
||||
openModal() {
|
||||
this.modal.open(ModalPassParams, { userId: 3141209 });
|
||||
}
|
||||
presentModal() {
|
||||
let modal = Modal.create(ModalPassData, { userId: 8675309 });
|
||||
this.nav.present(modal);
|
||||
|
||||
openToolbarModal() {
|
||||
this.modal.open(ToolbarModal).then(modalRef => {
|
||||
// modal has finished opening
|
||||
// modalRef is a reference to the modal instance
|
||||
modalRef.onClose = (modalData) => {
|
||||
// somehow modalRef.close(modalData) was called w/ modalData
|
||||
console.log('modalRef.onClose', modalData)
|
||||
}
|
||||
modal.data.subscribe(data => {
|
||||
console.log('data', data);
|
||||
});
|
||||
}
|
||||
|
||||
openModalChildNav() {
|
||||
this.modal.open(ContactUs, null, {
|
||||
handle: 'my-awesome-modal'
|
||||
});
|
||||
presentModalChildNav() {
|
||||
let modal = Modal.create(ContactUs);
|
||||
this.nav.present(modal);
|
||||
}
|
||||
|
||||
openModalCustomAnimation() {
|
||||
this.modal.open(ContactUs, null, {
|
||||
handle: 'my-awesome-modal',
|
||||
enterAnimation: 'my-fade-in',
|
||||
leaveAnimation: 'my-fade-out'
|
||||
presentToolbarModal() {
|
||||
let modal = Modal.create(ToolbarModal);
|
||||
this.nav.present(modal);
|
||||
}
|
||||
|
||||
presentModalCustomAnimation() {
|
||||
let modal = Modal.create(ContactUs);
|
||||
this.nav.present(modal, {
|
||||
animation: 'my-fade-in'
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -62,44 +58,65 @@ class E2EApp {
|
||||
|
||||
@Page({
|
||||
template: `
|
||||
<h3>Pass Params</h3>
|
||||
<p>User Id: {{userId}}</p>
|
||||
<p><button (click)="close()">Close Modal</button></p>
|
||||
<ion-navbar *navbar>
|
||||
<ion-title>Data in/out</ion-title>
|
||||
</ion-navbar>
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
<ion-input>
|
||||
<ion-label>UserId</ion-label>
|
||||
<input type="number" [(ngModel)]="data.userId">
|
||||
</ion-input>
|
||||
<ion-input>
|
||||
<ion-label>Name</ion-label>
|
||||
<input type="text" [(ngModel)]="data.name">
|
||||
</ion-input>
|
||||
</ion-list>
|
||||
<button full (click)="submit()">Submit</button>
|
||||
</ion-content>
|
||||
`
|
||||
})
|
||||
class ModalPassParams {
|
||||
constructor(private modal: Modal, params: NavParams) {
|
||||
this.userId = params.get('userId');
|
||||
class ModalPassData {
|
||||
constructor(params: NavParams, viewCtrl: ViewController) {
|
||||
this.data = {
|
||||
userId: params.get('userId'),
|
||||
name: 'Jenny'
|
||||
};
|
||||
this.viewCtrl = viewCtrl;
|
||||
}
|
||||
|
||||
submit() {
|
||||
this.viewCtrl.data.emit(this.data);
|
||||
this.viewCtrl.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Page({
|
||||
template: `
|
||||
<ion-toolbar>
|
||||
<ion-title>Modals</ion-title>
|
||||
<ion-toolbar primary>
|
||||
<ion-title>Toolbar 1</ion-title>
|
||||
</ion-toolbar>
|
||||
|
||||
<ion-toolbar primary>
|
||||
<ion-title>Another toolbar</ion-title>
|
||||
<ion-toolbar>
|
||||
<ion-title>Toolbar 2</ion-title>
|
||||
</ion-toolbar>
|
||||
|
||||
<ion-content padding>
|
||||
<button block danger (click)="closeModal()" class="e2eCloseToolbarModal">
|
||||
<icon close></icon>
|
||||
Close Modal
|
||||
<button block danger (click)="dismiss()" class="e2eCloseToolbarModal">
|
||||
Dismission Modal
|
||||
</button>
|
||||
</ion-content>
|
||||
`
|
||||
})
|
||||
class ToolbarModal {
|
||||
constructor(private modal: Modal) {}
|
||||
|
||||
closeModal() {
|
||||
this.close({
|
||||
adel: 'hello',
|
||||
lionel: 'hello'
|
||||
});
|
||||
constructor(viewCtrl: ViewController) {
|
||||
this.viewCtrl = viewCtrl;
|
||||
}
|
||||
|
||||
dismiss() {
|
||||
this.viewCtrl.dismiss();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -142,7 +159,7 @@ class ContactUs {
|
||||
<ion-navbar *navbar>
|
||||
<ion-title>First Page Header</ion-title>
|
||||
<ion-buttons start>
|
||||
<button class="e2eCloseMenu" (click)="closeModal()">Close</button>
|
||||
<button class="e2eCloseMenu" (click)="dismiss()">Close</button>
|
||||
</ion-buttons>
|
||||
</ion-navbar>
|
||||
<ion-content padding>
|
||||
@@ -152,23 +169,14 @@ class ContactUs {
|
||||
<p>
|
||||
<button (click)="openActionSheet()">Open Action Sheet</button>
|
||||
</p>
|
||||
<p>
|
||||
<button (click)="closeByHandeModal()">Close By Handle</button>
|
||||
</p>
|
||||
<f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f>
|
||||
<f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f><f></f>
|
||||
</ion-content>
|
||||
`
|
||||
})
|
||||
class ModalFirstPage {
|
||||
constructor(
|
||||
nav: NavController,
|
||||
modal: Modal,
|
||||
actionSheet: ActionSheet
|
||||
) {
|
||||
constructor(nav: NavController) {
|
||||
this.nav = nav;
|
||||
this.modal = modal;
|
||||
this.actionSheet = actionSheet;
|
||||
}
|
||||
|
||||
push() {
|
||||
@@ -179,12 +187,8 @@ class ModalFirstPage {
|
||||
this.nav.push(page, params, opts);
|
||||
}
|
||||
|
||||
closeModal() {
|
||||
this.modal.get().close();
|
||||
}
|
||||
|
||||
closeByHandeModal() {
|
||||
this.modal.get('my-awesome-modal').close();
|
||||
dismiss() {
|
||||
this.nav.rootNav.pop();
|
||||
}
|
||||
|
||||
openActionSheet() {
|
||||
@@ -239,6 +243,16 @@ class ModalSecondPage {
|
||||
}
|
||||
|
||||
|
||||
@App({
|
||||
template: '<ion-nav [root]="root"></ion-nav>'
|
||||
})
|
||||
class E2EApp {
|
||||
constructor() {
|
||||
this.root = E2EPage;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class FadeIn extends Animation {
|
||||
constructor(enteringView, leavingView) {
|
||||
super(enteringView.pageRef());
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
|
||||
<ion-navbar *navbar>
|
||||
<ion-title>Modals</ion-title>
|
||||
</ion-navbar>
|
||||
|
||||
<ion-content padding>
|
||||
<p>
|
||||
<button class="e2eOpenModal" (click)="openModalChildNav()">Open modal w/ child ion-nav</button>
|
||||
<button (click)="presentModal()">Present modal, pass params</button>
|
||||
</p>
|
||||
<p>
|
||||
<button (click)="openModal()">Open modal, pass params</button>
|
||||
<button class="e2eOpenModal" (click)="presentModalChildNav()">Present modal w/ child ion-nav</button>
|
||||
</p>
|
||||
<p>
|
||||
<button class="e2eOpenToolbarModal" (click)="openToolbarModal()">Open modal w/ toolbar</button>
|
||||
<button class="e2eOpenToolbarModal" (click)="presentToolbarModal()">Present modal w/ toolbar</button>
|
||||
</p>
|
||||
<p>
|
||||
<button (click)="openModalCustomAnimation()">Modal: Custom Animation</button>
|
||||
<button (click)="presentModalCustomAnimation()">Modal: Custom Animation</button>
|
||||
</p>
|
||||
</ion-content>
|
||||
|
||||
Reference in New Issue
Block a user