mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-26 08:13:34 +08:00
refactor(overlay): use NavController
This commit is contained in:
@ -254,10 +254,10 @@ export class Animation {
|
||||
});
|
||||
}
|
||||
|
||||
if (self._duration > 16 && this._opts.renderDelay > 0) {
|
||||
if (self._duration > 16 && self._opts.renderDelay > 0) {
|
||||
// begin each animation when everything is rendered in their starting point
|
||||
// give the browser some time to render everything in place before starting
|
||||
rafFrames(this._opts.renderDelay / 16, kickoff);
|
||||
rafFrames(self._opts.renderDelay / 16, kickoff);
|
||||
|
||||
} else {
|
||||
// no need to render everything in there place before animating in
|
||||
@ -538,6 +538,17 @@ export class Animation {
|
||||
return new AnimationClass(element);
|
||||
}
|
||||
|
||||
static createTransition(enteringView, leavingView, opts = {}) {
|
||||
const name = opts.animation || 'ios-transition';
|
||||
|
||||
let TransitionClass = AnimationRegistry[name];
|
||||
if (!TransitionClass) {
|
||||
TransitionClass = Animation;
|
||||
}
|
||||
|
||||
return new TransitionClass(enteringView, leavingView, opts);
|
||||
}
|
||||
|
||||
static register(name, AnimationClass) {
|
||||
AnimationRegistry[name] = AnimationClass;
|
||||
}
|
||||
@ -912,8 +923,9 @@ let AnimationRegistry = {};
|
||||
|
||||
function parallel(tasks, done) {
|
||||
var l = tasks.length;
|
||||
if (!l) {
|
||||
return done();
|
||||
if (!l ) {
|
||||
done && done();
|
||||
return;
|
||||
}
|
||||
|
||||
var completed = 0;
|
||||
@ -921,7 +933,7 @@ function parallel(tasks, done) {
|
||||
function taskCompleted() {
|
||||
completed++;
|
||||
if (completed === l) {
|
||||
done();
|
||||
done && done();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
import {Transition} from './transition';
|
||||
import {Animation} from '../animations/animation';
|
||||
import {Animation} from './animation';
|
||||
|
||||
const DURATION = 550;
|
||||
const EASING = 'cubic-bezier(0.36,0.66,0.04,1)';
|
||||
@ -14,7 +13,7 @@ const SHOW_BACK_BTN_CSS = 'show-back-button';
|
||||
|
||||
class IOSTransition extends Animation {
|
||||
|
||||
constructor(navCtrl, opts) {
|
||||
constructor(enteringView, leavingView, opts) {
|
||||
super(null, opts);
|
||||
|
||||
this.duration(DURATION);
|
||||
@ -23,10 +22,6 @@ class IOSTransition extends Animation {
|
||||
// what direction is the transition going
|
||||
let backDirection = (opts.direction === 'back');
|
||||
|
||||
// get entering/leaving views
|
||||
let enteringView = navCtrl.getStagedEnteringView();
|
||||
let leavingView = navCtrl.getStagedLeavingView();
|
||||
|
||||
// do they have navbars?
|
||||
let enteringHasNavbar = enteringView.hasNavbar();
|
||||
let leavingHasNavbar = leavingView && leavingView.hasNavbar();
|
||||
@ -189,4 +184,4 @@ class IOSTransition extends Animation {
|
||||
|
||||
}
|
||||
|
||||
Transition.register('ios', IOSTransition);
|
||||
Animation.register('ios-transition', IOSTransition);
|
@ -1,5 +1,4 @@
|
||||
import {Transition} from './transition';
|
||||
import {Animation} from '../animations/animation';
|
||||
import {Animation} from './animation';
|
||||
|
||||
const TRANSLATEY = 'translateY';
|
||||
const OFF_BOTTOM = '40px';
|
||||
@ -9,16 +8,12 @@ const SHOW_BACK_BTN_CSS = 'show-back-button';
|
||||
|
||||
class MDTransition extends Animation {
|
||||
|
||||
constructor(navCtrl, opts) {
|
||||
constructor(enteringView, leavingView, opts) {
|
||||
super(null, opts);
|
||||
|
||||
// what direction is the transition going
|
||||
let backDirection = (opts.direction === 'back');
|
||||
|
||||
// get entering/leaving views
|
||||
let enteringView = navCtrl.getStagedEnteringView();
|
||||
let leavingView = navCtrl.getStagedLeavingView();
|
||||
|
||||
// do they have navbars?
|
||||
let enteringHasNavbar = enteringView.hasNavbar();
|
||||
let leavingHasNavbar = leavingView && leavingView.hasNavbar();
|
||||
@ -61,4 +56,4 @@ class MDTransition extends Animation {
|
||||
|
||||
}
|
||||
|
||||
Transition.register('md', MDTransition);
|
||||
Animation.register('md-transition', MDTransition);
|
@ -5,14 +5,14 @@
|
||||
* @description
|
||||
* The ActionSheet is a modal menu with options to select based on an action.
|
||||
*/
|
||||
|
||||
import {Component, Injectable, NgFor, NgIf} from 'angular2/angular2';
|
||||
import {Component, Injectable, Renderer, NgFor, NgIf} from 'angular2/angular2';
|
||||
|
||||
import {OverlayController} from '../overlay/overlay-controller';
|
||||
import {Config} from '../../config/config';
|
||||
import {Icon} from '../icon/icon';
|
||||
import {Animation} from '../../animations/animation';
|
||||
import * as util from 'ionic/util';
|
||||
import {NavParams} from '../nav/nav-controller';
|
||||
import {extend} from '../../util/util';
|
||||
|
||||
|
||||
/**
|
||||
@ -56,48 +56,55 @@ import * as util from 'ionic/util';
|
||||
@Component({
|
||||
selector: 'ion-action-sheet',
|
||||
template:
|
||||
'<backdrop (click)="_cancel()" tappable disable-activated></backdrop>' +
|
||||
'<backdrop (click)="cancel()" tappable disable-activated></backdrop>' +
|
||||
'<action-sheet-wrapper>' +
|
||||
'<div class="action-sheet-container">' +
|
||||
'<div class="action-sheet-group action-sheet-options">' +
|
||||
'<div class="action-sheet-title" *ng-if="titleText">{{titleText}}</div>' +
|
||||
'<button (click)="_buttonClicked(i)" *ng-for="#b of buttons; #i=index" class="action-sheet-option disable-hover">' +
|
||||
'<div class="action-sheet-title" *ng-if="d.titleText">{{d.titleText}}</div>' +
|
||||
'<button (click)="buttonClicked(i)" *ng-for="#b of d.buttons; #i=index" class="action-sheet-option disable-hover">' +
|
||||
'<icon [name]="b.icon" *ng-if="b.icon"></icon> ' +
|
||||
'{{b.text}}' +
|
||||
'</button>' +
|
||||
'<button *ng-if="destructiveText" (click)="_destructive()" class="action-sheet-destructive disable-hover">' +
|
||||
'<icon [name]="destructiveIcon" *ng-if="destructiveIcon"></icon> ' +
|
||||
'{{destructiveText}}</button>' +
|
||||
'<button *ng-if="d.destructiveText" (click)="destructive()" class="action-sheet-destructive disable-hover">' +
|
||||
'<icon [name]="d.destructiveIcon" *ng-if="d.destructiveIcon"></icon> ' +
|
||||
'{{d.destructiveText}}</button>' +
|
||||
'</div>' +
|
||||
'<div class="action-sheet-group action-sheet-cancel" *ng-if="cancelText">' +
|
||||
'<button (click)="_cancel()" class=" disable-hover">' +
|
||||
'<icon [name]="cancelIcon"></icon> ' +
|
||||
'{{cancelText}}</button>' +
|
||||
'<div class="action-sheet-group action-sheet-cancel" *ng-if="d.cancelText">' +
|
||||
'<button (click)="cancel()" class="disable-hover">' +
|
||||
'<icon [name]="d.cancelIcon" *ng-if="d.cancelIcon"></icon> ' +
|
||||
'{{d.cancelText}}</button>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'</action-sheet-wrapper>',
|
||||
host: {
|
||||
'[style.zIndex]': '_zIndex'
|
||||
'[style.zIndex]': '_zIndex',
|
||||
'role': 'dialog'
|
||||
},
|
||||
directives: [NgFor, NgIf, Icon]
|
||||
})
|
||||
class ActionSheetCmp {
|
||||
|
||||
_cancel() {
|
||||
this.cancel && this.cancel();
|
||||
constructor(params: NavParams, renderer: Renderer) {
|
||||
this.d = params.data;
|
||||
|
||||
if (this.d.cssClass) {
|
||||
renderer.setElementClass(elementRef, this.d.cssClass, true);
|
||||
}
|
||||
}
|
||||
|
||||
cancel() {
|
||||
this.d.cancel && this.d.cancel();
|
||||
return this.close();
|
||||
}
|
||||
|
||||
_destructive() {
|
||||
let shouldClose = this.destructiveButtonClicked();
|
||||
if (shouldClose === true) {
|
||||
destructive() {
|
||||
if (this.d.destructiveButtonClicked()) {
|
||||
return this.close();
|
||||
}
|
||||
}
|
||||
|
||||
_buttonClicked(index) {
|
||||
let shouldClose = this.buttonClicked(index);
|
||||
if (shouldClose === true) {
|
||||
buttonClicked(index) {
|
||||
if (this.d.buttonClicked(index)) {
|
||||
return this.close();
|
||||
}
|
||||
}
|
||||
@ -109,12 +116,7 @@ export class ActionSheet {
|
||||
|
||||
constructor(ctrl: OverlayController, config: Config) {
|
||||
this.ctrl = ctrl;
|
||||
this._defaults = {
|
||||
enterAnimation: config.get('actionSheetEnter'),
|
||||
leaveAnimation: config.get('actionSheetLeave'),
|
||||
cancelIcon: config.get('actionSheetCancelIcon'),
|
||||
destructiveIcon: config.get('actionSheetDestructiveIcon')
|
||||
};
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -125,7 +127,15 @@ export class ActionSheet {
|
||||
* @return {Promise} Promise that resolves when the action sheet is open.
|
||||
*/
|
||||
open(opts={}) {
|
||||
return this.ctrl.open(OVERLAY_TYPE, ActionSheetCmp, util.extend(this._defaults, opts));
|
||||
opts = extend({
|
||||
pageType: OVERLAY_TYPE,
|
||||
enterAnimation: this.config.get('actionSheetEnter'),
|
||||
leaveAnimation: this.config.get('actionSheetLeave'),
|
||||
cancelIcon: this.config.get('actionSheetCancelIcon'),
|
||||
destructiveIcon: this.config.get('actionSheetDestructiveIcon')
|
||||
}, opts);
|
||||
|
||||
return this.ctrl.open(ActionSheetCmp, opts, opts);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -134,7 +144,7 @@ export class ActionSheet {
|
||||
*/
|
||||
get(handle) {
|
||||
if (handle) {
|
||||
return this.ctrl.getByHandle(handle, OVERLAY_TYPE);
|
||||
return this.ctrl.getByHandle(handle);
|
||||
}
|
||||
return this.ctrl.getByType(OVERLAY_TYPE);
|
||||
}
|
||||
@ -144,56 +154,70 @@ export class ActionSheet {
|
||||
const OVERLAY_TYPE = 'action-sheet';
|
||||
|
||||
|
||||
/**
|
||||
* Animations for action sheet
|
||||
*/
|
||||
class ActionSheetAnimation extends Animation {
|
||||
constructor(element) {
|
||||
super(element);
|
||||
this.easing('cubic-bezier(.36, .66, .04, 1)');
|
||||
|
||||
this.backdrop = new Animation(element.querySelector('backdrop'));
|
||||
this.wrapper = new Animation(element.querySelector('action-sheet-wrapper'));
|
||||
class ActionSheetSlideIn extends Animation {
|
||||
constructor(enteringView, leavingView, opts) {
|
||||
super(null, opts);
|
||||
|
||||
this.add(this.backdrop, this.wrapper);
|
||||
}
|
||||
}
|
||||
let ele = enteringView.pageRef().nativeElement;
|
||||
let backdrop = new Animation(ele.querySelector('backdrop'));
|
||||
let wrapper = new Animation(ele.querySelector('action-sheet-wrapper'));
|
||||
|
||||
class ActionSheetSlideIn extends ActionSheetAnimation {
|
||||
constructor(element) {
|
||||
super(element);
|
||||
this.duration(400);
|
||||
this.backdrop.fromTo('opacity', 0.01, 0.4);
|
||||
this.wrapper.fromTo('translateY', '100%', '0%');
|
||||
backdrop.fromTo('opacity', 0.01, 0.4);
|
||||
wrapper.fromTo('translateY', '100%', '0%');
|
||||
|
||||
this.easing('cubic-bezier(.36,.66,.04,1)').duration(400).add([backdrop, wrapper]);
|
||||
}
|
||||
}
|
||||
Animation.register('action-sheet-slide-in', ActionSheetSlideIn);
|
||||
|
||||
class ActionSheetSlideOut extends ActionSheetAnimation {
|
||||
constructor(element) {
|
||||
super(element);
|
||||
this.duration(300);
|
||||
this.backdrop.fromTo('opacity', 0.4, 0.01);
|
||||
this.wrapper.fromTo('translateY', '0%', '100%');
|
||||
|
||||
class ActionSheetSlideOut extends Animation {
|
||||
constructor(enteringView, leavingView, opts) {
|
||||
super(null, opts);
|
||||
|
||||
let ele = leavingView.pageRef().nativeElement;
|
||||
let backdrop = new Animation(ele.querySelector('backdrop'));
|
||||
let wrapper = new Animation(ele.querySelector('action-sheet-wrapper'));
|
||||
|
||||
backdrop.fromTo('opacity', 0.4, 0);
|
||||
wrapper.fromTo('translateY', '0%', '100%');
|
||||
|
||||
this.easing('cubic-bezier(.36,.66,.04,1)').duration(300).add([backdrop, wrapper]);
|
||||
}
|
||||
}
|
||||
Animation.register('action-sheet-slide-out', ActionSheetSlideOut);
|
||||
|
||||
|
||||
class ActionSheetMdSlideIn extends ActionSheetSlideIn {
|
||||
constructor(element) {
|
||||
super(element);
|
||||
this.duration(450);
|
||||
this.backdrop.fromTo('opacity', 0.01, 0.26);
|
||||
class ActionSheetMdSlideIn extends Animation {
|
||||
constructor(enteringView, leavingView, opts) {
|
||||
super(null, opts);
|
||||
|
||||
let ele = enteringView.pageRef().nativeElement;
|
||||
let backdrop = new Animation(ele.querySelector('backdrop'));
|
||||
let wrapper = new Animation(ele.querySelector('action-sheet-wrapper'));
|
||||
|
||||
backdrop.fromTo('opacity', 0.01, 0.26);
|
||||
wrapper.fromTo('translateY', '100%', '0%');
|
||||
|
||||
this.easing('cubic-bezier(.36,.66,.04,1)').duration(450).add([backdrop, wrapper]);
|
||||
}
|
||||
}
|
||||
Animation.register('action-sheet-md-slide-in', ActionSheetMdSlideIn);
|
||||
|
||||
class ActionSheetMdSlideOut extends ActionSheetSlideOut {
|
||||
constructor(element) {
|
||||
super(element);
|
||||
this.duration(450);
|
||||
this.backdrop.fromTo('opacity', 0.26, 0.01);
|
||||
|
||||
class ActionSheetMdSlideOut extends Animation {
|
||||
constructor(enteringView, leavingView, opts) {
|
||||
super(null, opts);
|
||||
|
||||
let ele = leavingView.pageRef().nativeElement;
|
||||
let backdrop = new Animation(ele.querySelector('backdrop'));
|
||||
let wrapper = new Animation(ele.querySelector('action-sheet-wrapper'));
|
||||
|
||||
backdrop.fromTo('opacity', 0.26, 0);
|
||||
wrapper.fromTo('translateY', '0%', '100%');
|
||||
|
||||
this.easing('cubic-bezier(.36,.66,.04,1)').duration(450).add([backdrop, wrapper]);
|
||||
}
|
||||
}
|
||||
Animation.register('action-sheet-md-slide-out', ActionSheetMdSlideOut);
|
||||
|
@ -23,17 +23,17 @@ class E2EApp {
|
||||
return items;
|
||||
}
|
||||
|
||||
didClick(ev, item) {
|
||||
console.log('CLICK', ev.defaultPrevented, ev)
|
||||
didClick(item) {
|
||||
console.log('CLICK')
|
||||
}
|
||||
|
||||
archive(ev, item) {
|
||||
console.log('Archive', ev, item);
|
||||
archive(item) {
|
||||
console.log('Archive', item);
|
||||
item.close();
|
||||
}
|
||||
|
||||
del(ev, item) {
|
||||
console.log('Delete', ev, item);
|
||||
del(item) {
|
||||
console.log('Delete', item);
|
||||
item.close();
|
||||
}
|
||||
|
||||
|
@ -10,15 +10,15 @@
|
||||
<ion-list id="myList">
|
||||
|
||||
<ion-item-sliding #item>
|
||||
<button ion-item text-wrap (click)="didClick($event, item)">
|
||||
<button ion-item text-wrap (click)="didClick(item)">
|
||||
<h3>Max Lynch</h3>
|
||||
<p>
|
||||
Hey do you want to go to the game tonight?
|
||||
</p>
|
||||
</button>
|
||||
<ion-item-options>
|
||||
<button primary (click)="archive($event, item)">Archive</button>
|
||||
<button danger (click)="del($event, item)">Delete</button>
|
||||
<button primary (click)="archive(item)">Archive</button>
|
||||
<button danger (click)="del(item)">Delete</button>
|
||||
</ion-item-options>
|
||||
</ion-item-sliding>
|
||||
|
||||
@ -30,8 +30,8 @@
|
||||
</p>
|
||||
</ion-item>
|
||||
<ion-item-options>
|
||||
<button primary (click)="archive($event, item)">Archive</button>
|
||||
<button danger (click)="del($event, item)"><icon trash></icon></button>
|
||||
<button primary (click)="archive(item)">Archive</button>
|
||||
<button danger (click)="del(item)"><icon trash></icon></button>
|
||||
</ion-item-options>
|
||||
</ion-item-sliding>
|
||||
|
||||
@ -43,8 +43,8 @@
|
||||
</p>
|
||||
</ion-item>
|
||||
<ion-item-options>
|
||||
<button primary (click)="archive($event, item)">Archive</button>
|
||||
<button danger (click)="del($event, item)">Delete</button>
|
||||
<button primary (click)="archive(item)">Archive</button>
|
||||
<button danger (click)="del(item)">Delete</button>
|
||||
</ion-item-options>
|
||||
</ion-item-sliding>
|
||||
|
||||
@ -54,7 +54,7 @@
|
||||
One Line w/ Icon, div only text
|
||||
</ion-item>
|
||||
<ion-item-options>
|
||||
<button primary (click)="archive($event, item)">Archive</button>
|
||||
<button primary (click)="archive(item)">Archive</button>
|
||||
</ion-item-options>
|
||||
</ion-item-sliding>
|
||||
|
||||
@ -66,7 +66,7 @@
|
||||
One Line w/ Avatar, div only text
|
||||
</ion-item>
|
||||
<ion-item-options>
|
||||
<button primary (click)="archive($event, item)">Archive</button>
|
||||
<button primary (click)="archive(item)">Archive</button>
|
||||
</ion-item-options>
|
||||
</ion-item-sliding>
|
||||
|
||||
@ -79,7 +79,7 @@
|
||||
<p>Paragraph text.</p>
|
||||
</ion-item>
|
||||
<ion-item-options>
|
||||
<button primary (click)="archive($event, item)">Archive</button>
|
||||
<button primary (click)="archive(item)">Archive</button>
|
||||
</ion-item-options>
|
||||
</ion-item-sliding>
|
||||
|
||||
@ -88,7 +88,7 @@
|
||||
<h3>ng-for {{data}}</h3>
|
||||
</ion-item>
|
||||
<ion-item-options>
|
||||
<button primary (click)="archive($event, item)">Archive</button>
|
||||
<button primary (click)="archive(item)">Archive</button>
|
||||
</ion-item-options>
|
||||
</ion-item-sliding>
|
||||
|
||||
|
@ -3,22 +3,24 @@ import {Injectable} from 'angular2/angular2';
|
||||
import {OverlayController} from '../overlay/overlay-controller';
|
||||
import {Config} from '../../config/config';
|
||||
import {Animation} from '../../animations/animation';
|
||||
import * as util from 'ionic/util';
|
||||
import {extend} from 'ionic/util';
|
||||
|
||||
/**
|
||||
* The Modal is a content pane that can go over the user's main view temporarily.
|
||||
* Usually used for making a choice or editing an item.
|
||||
* 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 NavController#push works, where you pass it a Page component,
|
||||
* along with optional Page params, and options for presenting the modal.
|
||||
*
|
||||
* @usage
|
||||
* ```ts
|
||||
* class MyApp {
|
||||
*
|
||||
* constructor(modal: Modal, app: IonicApp, Config: Config) {
|
||||
* constructor(modal: Modal) {
|
||||
* this.modal = modal;
|
||||
* }
|
||||
*
|
||||
* openModal() {
|
||||
* this.modal.open(ContactModal, {
|
||||
* this.modal.open(ContactPage, null, {
|
||||
* enterAnimation: 'my-fade-in',
|
||||
* leaveAnimation: 'my-fade-out',
|
||||
* handle: 'my-modal'
|
||||
@ -32,20 +34,24 @@ export class Modal {
|
||||
|
||||
constructor(ctrl: OverlayController, config: Config) {
|
||||
this.ctrl = ctrl;
|
||||
this._defaults = {
|
||||
enterAnimation: config.get('modalEnter') || 'modal-slide-in',
|
||||
leaveAnimation: config.get('modalLeave') || 'modal-slide-out',
|
||||
};
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {Type} componentType TODO
|
||||
* @param {Object} [opts={}] TODO
|
||||
* @returns {TODO} TODO
|
||||
* @param {TODO} componentType TODO
|
||||
* @param {TODO} [params={}] TODO
|
||||
* @param {TODO} [opts={}] TODO
|
||||
* @returns {Promise} TODO
|
||||
*/
|
||||
open(componentType: Type, opts={}) {
|
||||
return this.ctrl.open(OVERLAY_TYPE, componentType, util.extend(this._defaults, opts));
|
||||
open(componentType: Type, params={}, opts={}) {
|
||||
opts = extend({
|
||||
pageType: OVERLAY_TYPE,
|
||||
enterAnimation: this.config.get('modalEnter'),
|
||||
leaveAnimation: this.config.get('modalLeave'),
|
||||
}, opts);
|
||||
|
||||
return this.ctrl.open(componentType, params, opts);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -55,7 +61,7 @@ export class Modal {
|
||||
*/
|
||||
get(handle) {
|
||||
if (handle) {
|
||||
return this.ctrl.getByHandle(handle, OVERLAY_TYPE);
|
||||
return this.ctrl.getByHandle(handle);
|
||||
}
|
||||
return this.ctrl.getByType(OVERLAY_TYPE);
|
||||
}
|
||||
@ -69,20 +75,21 @@ const OVERLAY_TYPE = 'modal';
|
||||
* Animations for modals
|
||||
*/
|
||||
class ModalSlideIn extends Animation {
|
||||
constructor(element) {
|
||||
super(element);
|
||||
constructor(enteringView, leavingView, opts) {
|
||||
super(enteringView.pageRef(), opts);
|
||||
this
|
||||
.easing('cubic-bezier(0.36,0.66,0.04,1)')
|
||||
.duration(400)
|
||||
.fromTo('translateY', '100%', '0%');
|
||||
.fromTo('translateY', '100%', '0%')
|
||||
.before.addClass('show-page');
|
||||
}
|
||||
}
|
||||
Animation.register('modal-slide-in', ModalSlideIn);
|
||||
|
||||
|
||||
class ModalSlideOut extends Animation {
|
||||
constructor(element) {
|
||||
super(element);
|
||||
constructor(enteringView, leavingView, opts) {
|
||||
super(leavingView.pageRef(), opts);
|
||||
this
|
||||
.easing('ease-out')
|
||||
.duration(250)
|
||||
@ -93,21 +100,22 @@ Animation.register('modal-slide-out', ModalSlideOut);
|
||||
|
||||
|
||||
class ModalMDSlideIn extends Animation {
|
||||
constructor(element) {
|
||||
super(element);
|
||||
constructor(enteringView, leavingView, opts) {
|
||||
super(enteringView.pageRef(), opts);
|
||||
this
|
||||
.easing('cubic-bezier(0.36,0.66,0.04,1)')
|
||||
.duration(280)
|
||||
.fromTo('translateY', '40px', '0px')
|
||||
.fadeIn();
|
||||
.fadeIn()
|
||||
.before.addClass('show-page');
|
||||
}
|
||||
}
|
||||
Animation.register('modal-md-slide-in', ModalMDSlideIn);
|
||||
|
||||
|
||||
class ModalMDSlideOut extends Animation {
|
||||
constructor(element) {
|
||||
super(element);
|
||||
constructor(enteringView, leavingView, opts) {
|
||||
super(leavingView.pageRef(), opts);
|
||||
this
|
||||
.duration(200)
|
||||
.easing('cubic-bezier(0.47,0,0.745,0.715)')
|
||||
|
@ -1,13 +1,13 @@
|
||||
import {App, Page, IonicApp, Config, Platform} from 'ionic/ionic';
|
||||
import {App, Page, Config, Platform} from 'ionic/ionic';
|
||||
import {Modal, ActionSheet, NavController, NavParams, Animation} from 'ionic/ionic';
|
||||
|
||||
|
||||
@App({
|
||||
templateUrl: 'main.html'
|
||||
})
|
||||
class MyAppCmp {
|
||||
class E2EApp {
|
||||
|
||||
constructor(modal: Modal, app: IonicApp, config: Config, platform: Platform) {
|
||||
constructor(modal: Modal, config: Config, platform: Platform) {
|
||||
this.modal = modal;
|
||||
|
||||
console.log('platforms', platform.platforms());
|
||||
@ -25,7 +25,7 @@ class MyAppCmp {
|
||||
console.log('windows phone', platform.is('windowsphone'))
|
||||
|
||||
platform.ready().then(() => {
|
||||
console.log('platform.ready')
|
||||
console.log('platform.ready');
|
||||
});
|
||||
}
|
||||
|
||||
@ -38,13 +38,14 @@ class MyAppCmp {
|
||||
}
|
||||
|
||||
openModalChildNav() {
|
||||
this.modal.open(ContactModal, {
|
||||
this.modal.open(ContactUs, null, {
|
||||
handle: 'my-awesome-modal'
|
||||
});
|
||||
}
|
||||
|
||||
openModalCustomAnimation() {
|
||||
this.modal.open(ContactModal, {
|
||||
this.modal.open(ContactUs, null, {
|
||||
handle: 'my-awesome-modal',
|
||||
enterAnimation: 'my-fade-in',
|
||||
leaveAnimation: 'my-fade-out'
|
||||
});
|
||||
@ -67,21 +68,22 @@ class PlainPage {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Page({
|
||||
template: `
|
||||
<ion-toolbar>
|
||||
<ion-title>Modals</ion-title>
|
||||
</ion-toolbar>
|
||||
|
||||
<ion-toolbar primary>
|
||||
<ion-title>Another toolbar</ion-title>
|
||||
</ion-toolbar>
|
||||
|
||||
|
||||
<ion-content padding>
|
||||
<button block danger (click)="closeModal()" class="e2eCloseToolbarModal">
|
||||
<icon close></icon>
|
||||
Close Modal
|
||||
</button>
|
||||
<button block danger (click)="closeModal()" class="e2eCloseToolbarModal">
|
||||
<icon close></icon>
|
||||
Close Modal
|
||||
</button>
|
||||
</ion-content>
|
||||
`
|
||||
})
|
||||
@ -97,38 +99,43 @@ class ToolbarModal {
|
||||
@Page({
|
||||
template: '<ion-nav [root]="rootView"></ion-nav>'
|
||||
})
|
||||
class ContactModal {
|
||||
class ContactUs {
|
||||
constructor() {
|
||||
console.log('ContactModal constructor')
|
||||
console.log('ContactUs constructor');
|
||||
this.rootView = ModalFirstPage;
|
||||
}
|
||||
onPageLoaded() {
|
||||
console.log('ContactModal onPageLoaded');
|
||||
console.log('ContactUs onPageLoaded');
|
||||
}
|
||||
onPageWillEnter() {
|
||||
console.log('ContactModal onPageWillEnter');
|
||||
console.log('ContactUs onPageWillEnter');
|
||||
}
|
||||
onPageDidEnter() {
|
||||
console.log('ContactModal onPageDidEnter');
|
||||
console.log('ContactUs onPageDidEnter');
|
||||
}
|
||||
onPageWillLeave() {
|
||||
console.log('ContactModal onPageWillLeave');
|
||||
console.log('ContactUs onPageWillLeave');
|
||||
}
|
||||
onPageDidLeave() {
|
||||
console.log('ContactModal onPageDidLeave');
|
||||
console.log('ContactUs onPageDidLeave');
|
||||
}
|
||||
onPageWillUnload() {
|
||||
console.log('ContactModal onPageWillUnload');
|
||||
console.log('ContactUs onPageWillUnload');
|
||||
}
|
||||
onPageDidUnload() {
|
||||
console.log('ContactModal onPageDidUnload');
|
||||
console.log('ContactUs onPageDidUnload');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Page({
|
||||
template: `
|
||||
<ion-navbar *navbar><ion-title>First Page Header</ion-title><ion-nav-items primary><button class="e2eCloseMenu" (click)="closeModal()">Close</button></ion-nav-items></ion-navbar>
|
||||
<ion-navbar *navbar>
|
||||
<ion-title>First Page Header</ion-title>
|
||||
<ion-nav-items primary>
|
||||
<button class="e2eCloseMenu" (click)="closeModal()">Close</button>
|
||||
</ion-nav-items>
|
||||
</ion-navbar>
|
||||
<ion-content padding>
|
||||
<p>
|
||||
<button (click)="push()">Push (Go to 2nd)</button>
|
||||
@ -156,17 +163,19 @@ class ModalFirstPage {
|
||||
}
|
||||
|
||||
push() {
|
||||
this.nav.push(ModalSecondPage, { id: 8675309, myData: [1,2,3,4] }, { animation: 'ios' });
|
||||
let page = ModalSecondPage;
|
||||
let params = { id: 8675309, myData: [1,2,3,4] };
|
||||
let opts = { animation: 'ios' };
|
||||
|
||||
this.nav.push(page, params, opts);
|
||||
}
|
||||
|
||||
closeModal() {
|
||||
let modal = this.modal.get();
|
||||
modal.close();
|
||||
this.modal.get().close();
|
||||
}
|
||||
|
||||
closeByHandeModal() {
|
||||
let modal = this.modal.get('my-awesome-modal');
|
||||
modal.close();
|
||||
this.modal.get('my-awesome-modal').close();
|
||||
}
|
||||
|
||||
openActionSheet() {
|
||||
@ -198,7 +207,9 @@ class ModalFirstPage {
|
||||
|
||||
@Page({
|
||||
template: `
|
||||
<ion-navbar *navbar><ion-title>Second Page Header</ion-title></ion-navbar>
|
||||
<ion-navbar *navbar>
|
||||
<ion-title>Second Page Header</ion-title>
|
||||
</ion-navbar>
|
||||
<ion-content padding>
|
||||
<p>
|
||||
<button (click)="nav.pop()">Pop (Go back to 1st)</button>
|
||||
@ -214,32 +225,32 @@ class ModalSecondPage {
|
||||
params: NavParams
|
||||
) {
|
||||
this.nav = nav;
|
||||
this.params = params;
|
||||
|
||||
console.log('Second page params:', params);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class FadeIn extends Animation {
|
||||
constructor(element) {
|
||||
super(element);
|
||||
constructor(enteringView, leavingView) {
|
||||
super(enteringView.pageRef());
|
||||
this
|
||||
.easing('ease')
|
||||
.duration(450)
|
||||
.fadeIn();
|
||||
.duration(1000)
|
||||
.fromTo('translateY', '0%', '0%')
|
||||
.fadeIn()
|
||||
.before.addClass('show-page');
|
||||
}
|
||||
}
|
||||
Animation.register('my-fade-in', FadeIn);
|
||||
|
||||
class FadeOut extends Animation {
|
||||
constructor(element) {
|
||||
super(element);
|
||||
constructor(enteringView, leavingView) {
|
||||
super(leavingView.pageRef());
|
||||
this
|
||||
.easing('ease')
|
||||
.duration(250)
|
||||
.fadeOut();
|
||||
.duration(500)
|
||||
.fadeOut()
|
||||
.before.addClass('show-page');
|
||||
}
|
||||
}
|
||||
Animation.register('my-fade-out', FadeOut);
|
||||
|
@ -4,7 +4,7 @@ import {Ion} from '../ion';
|
||||
import {IonicApp} from '../app/app';
|
||||
import {Config} from '../../config/config';
|
||||
import {ViewController} from './view-controller';
|
||||
import {Transition} from '../../transitions/transition';
|
||||
import {Animation} from '../../animations/animation';
|
||||
import {SwipeBackGesture} from './swipe-back';
|
||||
import * as util from 'ionic/util';
|
||||
import {raf} from '../../util/dom';
|
||||
@ -158,7 +158,7 @@ export class NavController extends Ion {
|
||||
let promise = new Promise(res => { resolve = res; });
|
||||
|
||||
// do not animate if this is the first in the stack
|
||||
if (!this._views.length) {
|
||||
if (!this._views.length && !opts.animateFirst) {
|
||||
opts.animate = false;
|
||||
}
|
||||
|
||||
@ -177,6 +177,8 @@ export class NavController extends Ion {
|
||||
let enteringView = new ViewController(this, componentType, params);
|
||||
enteringView.shouldDestroy = false;
|
||||
enteringView.shouldCache = false;
|
||||
enteringView.pageType = opts.pageType;
|
||||
enteringView.handle = opts.handle || null;
|
||||
|
||||
// add the view to the stack
|
||||
this._add(enteringView);
|
||||
@ -202,7 +204,7 @@ export class NavController extends Ion {
|
||||
* @returns {Promise} TODO
|
||||
*/
|
||||
pop(opts = {}) {
|
||||
if (!this.canGoBack()) {
|
||||
if (!opts.animateFirst && !this.canGoBack()) {
|
||||
return Promise.reject();
|
||||
}
|
||||
|
||||
@ -225,20 +227,14 @@ export class NavController extends Ion {
|
||||
// Note: we might not have an entering view if this is the
|
||||
// only view on the history stack.
|
||||
let enteringView = this.getPrevious(leavingView);
|
||||
if (enteringView) {
|
||||
if (this.router) {
|
||||
// notify router of the state change
|
||||
this.router.stateChange('pop', enteringView);
|
||||
}
|
||||
|
||||
// start the transition
|
||||
this._transition(enteringView, leavingView, opts, resolve);
|
||||
|
||||
} else {
|
||||
this._transComplete();
|
||||
resolve();
|
||||
if (this.router) {
|
||||
// notify router of the state change
|
||||
this.router.stateChange('pop', enteringView);
|
||||
}
|
||||
|
||||
// start the transition
|
||||
this._transition(enteringView, leavingView, opts, resolve);
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
@ -429,8 +425,8 @@ export class NavController extends Ion {
|
||||
* @returns {any} TODO
|
||||
*/
|
||||
_transition(enteringView, leavingView, opts, done) {
|
||||
if (!enteringView || enteringView === leavingView) {
|
||||
return done();
|
||||
if (enteringView === leavingView) {
|
||||
return done(enteringView);
|
||||
}
|
||||
|
||||
if (!opts.animation) {
|
||||
@ -440,15 +436,21 @@ export class NavController extends Ion {
|
||||
opts.animate = false;
|
||||
}
|
||||
|
||||
if (!enteringView) {
|
||||
// if not entering view then create a bogus one
|
||||
enteringView = new ViewController()
|
||||
enteringView.loaded();
|
||||
}
|
||||
|
||||
// wait for the new view to complete setup
|
||||
this._stage(enteringView, () => {
|
||||
|
||||
if (enteringView.shouldDestroy) {
|
||||
// already marked as a view that will be destroyed, don't continue
|
||||
return done();
|
||||
return done(enteringView);
|
||||
}
|
||||
|
||||
this._setZIndex(enteringView.instance, leavingView && leavingView.instance, opts.direction);
|
||||
this._setZIndex(enteringView.instance, leavingView.instance, opts.direction);
|
||||
|
||||
this._zone.runOutsideAngular(() => {
|
||||
|
||||
@ -466,8 +468,11 @@ export class NavController extends Ion {
|
||||
leavingView.state = STAGED_LEAVING_STATE;
|
||||
|
||||
// init the transition animation
|
||||
opts.renderDelay = this.config.get('pageTransitionDelay');
|
||||
let transAnimation = Transition.create(this, opts);
|
||||
opts.renderDelay = opts.transitionDelay || this.config.get('pageTransitionDelay');
|
||||
|
||||
let transAnimation = Animation.createTransition(this._getStagedEntering(),
|
||||
this._getStagedLeaving(),
|
||||
opts);
|
||||
if (opts.animate === false) {
|
||||
// force it to not animate the elements, just apply the "to" styles
|
||||
transAnimation.clearDuration();
|
||||
@ -482,9 +487,12 @@ export class NavController extends Ion {
|
||||
this.app.setTransitioning(true, duration);
|
||||
}
|
||||
|
||||
if (opts.pageType) {
|
||||
transAnimation.before.addClass(opts.pageType);
|
||||
}
|
||||
|
||||
// start the transition
|
||||
transAnimation.play(() => {
|
||||
|
||||
// transition has completed, update each view's state
|
||||
enteringView.state = ACTIVE_STATE;
|
||||
leavingView.state = CACHED_STATE;
|
||||
@ -500,7 +508,7 @@ export class NavController extends Ion {
|
||||
// all done!
|
||||
this._zone.run(() => {
|
||||
this._transComplete();
|
||||
done();
|
||||
done(enteringView);
|
||||
});
|
||||
});
|
||||
|
||||
@ -514,7 +522,7 @@ export class NavController extends Ion {
|
||||
* @private
|
||||
*/
|
||||
_stage(viewCtrl, done) {
|
||||
if (viewCtrl.instance || viewCtrl.shouldDestroy) {
|
||||
if (viewCtrl.isLoaded() || viewCtrl.shouldDestroy) {
|
||||
// already compiled this view
|
||||
return done();
|
||||
}
|
||||
@ -685,8 +693,8 @@ export class NavController extends Ion {
|
||||
|
||||
this._zone.run(() => {
|
||||
// find the views that were entering and leaving
|
||||
let enteringView = this.getStagedEnteringView();
|
||||
let leavingView = this.getStagedLeavingView();
|
||||
let enteringView = this._getStagedEntering();
|
||||
let leavingView = this._getStagedLeaving();
|
||||
|
||||
if (enteringView && leavingView) {
|
||||
// finish up the animation
|
||||
@ -883,29 +891,50 @@ export class NavController extends Ion {
|
||||
|
||||
/**
|
||||
* @private
|
||||
* TODO
|
||||
* @param {TODO} view TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
_add(view) {
|
||||
this._incrementId(view);
|
||||
this._views.push(view);
|
||||
}
|
||||
|
||||
_incrementId(view) {
|
||||
view.id = this.id + '-' + (++this._ids);
|
||||
_add(viewCtrl) {
|
||||
this._incrementId(viewCtrl);
|
||||
this._views.push(viewCtrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_incrementId(viewCtrl) {
|
||||
viewCtrl.id = this.id + '-' + (++this._ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* TODO
|
||||
* @param {TODO} viewOrIndex TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
_remove(viewOrIndex) {
|
||||
util.array.remove(this._views, viewOrIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_getStagedEntering() {
|
||||
for (let i = 0, ii = this._views.length; i < ii; i++) {
|
||||
if (this._views[i].state === STAGED_ENTERING_STATE) {
|
||||
return this._views[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_getStagedLeaving() {
|
||||
for (let i = 0, ii = this._views.length; i < ii; i++) {
|
||||
if (this._views[i].state === STAGED_LEAVING_STATE) {
|
||||
return this._views[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @returns {TODO} TODO
|
||||
@ -931,14 +960,42 @@ export class NavController extends Ion {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} handle TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
getByHandle(handle) {
|
||||
for (let i = 0, ii = this._views.length; i < ii; i++) {
|
||||
if (this._views[i].handle === handle) {
|
||||
return this._views[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} pageType TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
getByType(pageType) {
|
||||
for (let i = 0, ii = this._views.length; i < ii; i++) {
|
||||
if (this._views[i].pageType === pageType) {
|
||||
return this._views[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} view TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
getPrevious(view) {
|
||||
if (view) {
|
||||
let viewIndex = this._views.indexOf(view);
|
||||
getPrevious(viewCtrl) {
|
||||
if (viewCtrl) {
|
||||
let viewIndex = this._views.indexOf(viewCtrl);
|
||||
|
||||
for (let i = viewIndex - 1; i >= 0; i--) {
|
||||
if (!this._views[i].shouldDestroy) {
|
||||
@ -949,32 +1006,6 @@ export class NavController extends Ion {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
getStagedEnteringView() {
|
||||
for (let i = 0, ii = this._views.length; i < ii; i++) {
|
||||
if (this._views[i].state === STAGED_ENTERING_STATE) {
|
||||
return this._views[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
getStagedLeavingView() {
|
||||
for (let i = 0, ii = this._views.length; i < ii; i++) {
|
||||
if (this._views[i].state === STAGED_LEAVING_STATE) {
|
||||
return this._views[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* First view in this nav controller's stack. This would
|
||||
* not return an view which is about to be destroyed.
|
||||
@ -1008,8 +1039,8 @@ export class NavController extends Ion {
|
||||
* @param {TODO} view TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
indexOf(view) {
|
||||
return this._views.indexOf(view);
|
||||
indexOf(viewCtrl) {
|
||||
return this._views.indexOf(viewCtrl);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1027,36 +1058,13 @@ export class NavController extends Ion {
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
instances() {
|
||||
let instances = [];
|
||||
for (let view of this._views) {
|
||||
if (view.instance) {
|
||||
instances.push(view.instance);
|
||||
}
|
||||
}
|
||||
return instances;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} view TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
isActive(view) {
|
||||
return (view && view.state === ACTIVE_STATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} view TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
isStagedEntering(view) {
|
||||
return (view && view.state === STAGED_ENTERING_STATE);
|
||||
isActive(viewCtrl) {
|
||||
return (viewCtrl && viewCtrl.state === ACTIVE_STATE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -10,9 +10,10 @@ export class ViewController {
|
||||
this.navCtrl = navCtrl;
|
||||
this.componentType = componentType;
|
||||
this.params = new NavParams(params);
|
||||
this.instance = null;
|
||||
this.instance = {};
|
||||
this.state = 0;
|
||||
this._destroys = [];
|
||||
this._loaded = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -142,6 +143,10 @@ export class ViewController {
|
||||
}
|
||||
}
|
||||
|
||||
isLoaded() {
|
||||
return this._loaded;
|
||||
}
|
||||
|
||||
/**
|
||||
* The view has loaded. This event only happens once per view being
|
||||
* created. If a view leaves but is cached, then this will not
|
||||
@ -150,8 +155,9 @@ export class ViewController {
|
||||
* recommended method to use when a view becomes active.
|
||||
*/
|
||||
loaded() {
|
||||
this._loaded = true;
|
||||
if (!this.shouldDestroy) {
|
||||
this.instance && this.instance.onPageLoaded && this.instance.onPageLoaded();
|
||||
this.instance.onPageLoaded && this.instance.onPageLoaded();
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,7 +166,7 @@ export class ViewController {
|
||||
*/
|
||||
willEnter() {
|
||||
if (!this.shouldDestroy) {
|
||||
this.instance && this.instance.onPageWillEnter && this.instance.onPageWillEnter();
|
||||
this.instance.onPageWillEnter && this.instance.onPageWillEnter();
|
||||
}
|
||||
}
|
||||
|
||||
@ -171,14 +177,14 @@ export class ViewController {
|
||||
didEnter() {
|
||||
let navbar = this.getNavbar();
|
||||
navbar && navbar.didEnter();
|
||||
this.instance && this.instance.onPageDidEnter && this.instance.onPageDidEnter();
|
||||
this.instance.onPageDidEnter && this.instance.onPageDidEnter();
|
||||
}
|
||||
|
||||
/**
|
||||
* The view has is about to leave and no longer be the active view.
|
||||
*/
|
||||
willLeave() {
|
||||
this.instance && this.instance.onPageWillLeave && this.instance.onPageWillLeave();
|
||||
this.instance.onPageWillLeave && this.instance.onPageWillLeave();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -186,27 +192,25 @@ export class ViewController {
|
||||
* will fire, whether it is cached or unloaded.
|
||||
*/
|
||||
didLeave() {
|
||||
this.instance && this.instance.onPageDidLeave && this.instance.onPageDidLeave();
|
||||
this.instance.onPageDidLeave && this.instance.onPageDidLeave();
|
||||
}
|
||||
|
||||
/**
|
||||
* The view is about to be destroyed and have its elements removed.
|
||||
*/
|
||||
willUnload() {
|
||||
this.instance && this.instance.onPageWillUnload && this.instance.onPageWillUnload();
|
||||
this.instance.onPageWillUnload && this.instance.onPageWillUnload();
|
||||
}
|
||||
|
||||
/**
|
||||
* The view has been destroyed and its elements have been removed.
|
||||
*/
|
||||
didUnload() {
|
||||
this.instance && this.instance.onPageDidUnload && this.instance.onPageDidUnload();
|
||||
this.instance.onPageDidUnload && this.instance.onPageDidUnload();
|
||||
}
|
||||
|
||||
domCache(isActiveView, isPreviousView) {
|
||||
if (this.instance) {
|
||||
this.instance._hidden = (!isActiveView && !isPreviousView);
|
||||
}
|
||||
this.instance._hidden = (!isActiveView && !isPreviousView);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,164 +1,43 @@
|
||||
import {Component, NgZone, Injectable, Renderer} from 'angular2/angular2';
|
||||
|
||||
import {IonicApp} from '../app/app';
|
||||
import {Config} from '../../config/config';
|
||||
import {Animation} from '../../animations/animation';
|
||||
import * as util from 'ionic/util';
|
||||
import {extend} from 'ionic/util';
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class OverlayController {
|
||||
|
||||
constructor(app: IonicApp, config: Config, zone: NgZone, renderer: Renderer) {
|
||||
this.app = app;
|
||||
this.config = config;
|
||||
this.zone = zone;
|
||||
this.renderer = renderer;
|
||||
this.refs = [];
|
||||
}
|
||||
|
||||
open(overlayType, componentType: Type, opts={}) {
|
||||
if (!this.anchor) {
|
||||
console.error('<ion-overlay></ion-overlay> required in root component template to use: ' + overlayType);
|
||||
open(componentType, params = {}, opts = {}) {
|
||||
if (!this.nav) {
|
||||
console.error('<ion-overlay></ion-overlay> required in root template (app.html) to use: ' + overlayType);
|
||||
return Promise.reject();
|
||||
}
|
||||
|
||||
let resolve, reject;
|
||||
let promise = new Promise((res, rej) => { resolve = res; reject = rej; });
|
||||
|
||||
try {
|
||||
this.anchor.append(componentType).then(ref => {
|
||||
let instance = ref && ref.instance;
|
||||
if (!instance) {
|
||||
return reject();
|
||||
}
|
||||
opts.animation = opts.enterAnimation;
|
||||
opts.animateFirst = true;
|
||||
|
||||
instance._zIndex = ROOT_Z_INDEX;
|
||||
for (let i = 0; i < this.refs.length; i++) {
|
||||
if (this.refs[i].instance._zIndex >= ref.instance._zIndex) {
|
||||
ref.instance._zIndex = this.refs[i].instance._zIndex + 1;
|
||||
}
|
||||
}
|
||||
this.renderer.setElementAttribute(ref.location, 'role', 'dialog');
|
||||
|
||||
util.extend(instance, opts);
|
||||
|
||||
ref._type = overlayType;
|
||||
ref._handle = opts.handle || (overlayType + ref._z);
|
||||
|
||||
this.add(ref);
|
||||
|
||||
instance.close = (closeOpts={}) => {
|
||||
this.close(ref, util.extend(opts, closeOpts));
|
||||
this.nav.push(componentType, params, opts).then(enteringView => {
|
||||
if (enteringView && enteringView.instance) {
|
||||
enteringView.instance.close = (closeOpts={}) => {
|
||||
extend(opts, closeOpts);
|
||||
opts.animation = opts.leaveAnimation;
|
||||
this.nav.pop(opts);
|
||||
};
|
||||
|
||||
instance.onPageLoaded && instance.onPageLoaded();
|
||||
instance.onPageWillEnter && instance.onPageWillEnter();
|
||||
|
||||
let animation = Animation.create(ref.location.nativeElement, opts.enterAnimation);
|
||||
if (this.config.get('animate') === false) {
|
||||
animation.duration(0);
|
||||
}
|
||||
animation.before.addClass(overlayType);
|
||||
if (overlayType == 'modal') {
|
||||
animation.before.addClass('show-page');
|
||||
}
|
||||
|
||||
this.app.setEnabled(false, animation.duration());
|
||||
this.app.setTransitioning(true, animation.duration());
|
||||
|
||||
this.zone.runOutsideAngular(() => {
|
||||
|
||||
animation.play().then(() => {
|
||||
animation.dispose();
|
||||
|
||||
this.zone.run(() => {
|
||||
this.app.setEnabled(true);
|
||||
this.app.setTransitioning(false);
|
||||
instance.onPageDidEnter && instance.onPageDidEnter();
|
||||
resolve(instance);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}).catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
resolve();
|
||||
})
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
close(ref, opts) {
|
||||
let resolve;
|
||||
let promise = new Promise(res => { resolve = res; });
|
||||
|
||||
let instance = ref.instance;
|
||||
instance.onPageWillLeave && instance.onPageWillLeave();
|
||||
instance.onPageWillUnload && instance.onPageWillUnload();
|
||||
|
||||
let animation = Animation.create(ref.location.nativeElement, opts.leaveAnimation);
|
||||
if (this.config.get('animate') === false) {
|
||||
animation.duration(0);
|
||||
}
|
||||
|
||||
this.app.setEnabled(false, animation.duration());
|
||||
this.app.setTransitioning(true, animation.duration());
|
||||
|
||||
this.zone.runOutsideAngular(() => {
|
||||
|
||||
animation.play().then(() => {
|
||||
animation.dispose();
|
||||
|
||||
this.zone.run(() => {
|
||||
instance.onPageDidLeave && instance.onPageDidLeave();
|
||||
instance.onPageDidUnload && instance.onPageDidUnload();
|
||||
|
||||
this.app.setEnabled(true);
|
||||
this.app.setTransitioning(false);
|
||||
|
||||
this.remove(ref);
|
||||
|
||||
resolve();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
add(ref) {
|
||||
this.refs.push(ref);
|
||||
}
|
||||
|
||||
remove(ref) {
|
||||
util.array.remove(this.refs, ref);
|
||||
ref.dispose && ref.dispose();
|
||||
}
|
||||
|
||||
getByType(overlayType) {
|
||||
for (let i = this.refs.length - 1; i >= 0; i--) {
|
||||
if (overlayType === this.refs[i]._type) {
|
||||
return this.refs[i].instance;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
let overlay = this.nav.getByType(overlayType);
|
||||
return overlay && overlay.instance;
|
||||
}
|
||||
|
||||
getByHandle(handle, overlayType) {
|
||||
for (let i = this.refs.length - 1; i >= 0; i--) {
|
||||
if (handle === this.refs[i]._handle && overlayType === this.refs[i]._type) {
|
||||
return this.refs[i].instance;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
let overlay = this.nav.getByHandle(handle);
|
||||
return overlay && overlay.instance;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,33 +1,35 @@
|
||||
import {Component, ElementRef, DynamicComponentLoader} from 'angular2/angular2';
|
||||
import {Component, ElementRef, Compiler, DynamicComponentLoader, AppViewManager, NgZone, Renderer} from 'angular2/angular2';
|
||||
|
||||
import {IonicApp} from '../app/app';
|
||||
import {Config} from '../../config/config';
|
||||
import {OverlayController} from './overlay-controller';
|
||||
import {NavController} from '../nav/nav-controller';
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
@Component({
|
||||
selector: 'ion-overlay',
|
||||
template: '<template #contents></template>'
|
||||
})
|
||||
export class OverlayAnchor {
|
||||
export class OverlayNav extends NavController {
|
||||
|
||||
constructor(
|
||||
overlayCtrl: OverlayController,
|
||||
app: IonicApp,
|
||||
config: Config,
|
||||
elementRef: ElementRef,
|
||||
loader: DynamicComponentLoader
|
||||
compiler: Compiler,
|
||||
loader: DynamicComponentLoader,
|
||||
viewManager: AppViewManager,
|
||||
zone: NgZone,
|
||||
renderer: Renderer
|
||||
) {
|
||||
super(null, app, config, elementRef, compiler, loader, viewManager, zone, renderer);
|
||||
|
||||
if (overlayCtrl.anchor) {
|
||||
throw ('An app should only have one <ion-overlay></ion-overlay>');
|
||||
}
|
||||
|
||||
this.elementRef = elementRef;
|
||||
this.loader = loader;
|
||||
overlayCtrl.anchor = this;
|
||||
overlayCtrl.nav = this;
|
||||
}
|
||||
|
||||
append(componentType) {
|
||||
return this.loader.loadIntoLocation(componentType, this.elementRef, 'contents').catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,12 @@
|
||||
import {FORM_DIRECTIVES, NgControl, NgControlGroup,
|
||||
Component, ElementRef, Injectable, NgClass, NgIf, NgFor} from 'angular2/angular2';
|
||||
Component, ElementRef, Injectable, NgClass, NgIf, NgFor, Renderer} from 'angular2/angular2';
|
||||
|
||||
import {OverlayController} from '../overlay/overlay-controller';
|
||||
import {Config} from '../../config/config';
|
||||
import {Animation} from '../../animations/animation';
|
||||
import {NavParams} from '../nav/nav-controller';
|
||||
import {Button} from '../button/button';
|
||||
import * as util from 'ionic/util';
|
||||
import {extend} from '../../util/util';
|
||||
|
||||
|
||||
/**
|
||||
@ -66,10 +67,7 @@ export class Popup {
|
||||
|
||||
constructor(ctrl: OverlayController, config: Config) {
|
||||
this.ctrl = ctrl;
|
||||
this._defaults = {
|
||||
enterAnimation: config.get('popupEnter'),
|
||||
leaveAnimation: config.get('popupLeave'),
|
||||
};
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -82,9 +80,13 @@ export class Popup {
|
||||
opts.promiseResolve = resolve;
|
||||
opts.promiseReject = reject;
|
||||
|
||||
let defaults = util.merge({}, this._defaults);
|
||||
opts = extend({
|
||||
pageType: OVERLAY_TYPE,
|
||||
enterAnimation: this.config.get('popupEnter'),
|
||||
leaveAnimation: this.config.get('popupLeave')
|
||||
}, opts);
|
||||
|
||||
return this.ctrl.open(OVERLAY_TYPE, PopupCmp, util.extend(defaults, opts));
|
||||
return this.ctrl.open(PopupCmp, opts, opts);
|
||||
});
|
||||
}
|
||||
|
||||
@ -122,7 +124,7 @@ export class Popup {
|
||||
//resolve();
|
||||
}
|
||||
};
|
||||
opts = util.extend({
|
||||
opts = extend({
|
||||
showPrompt: false,
|
||||
cancel: () => {
|
||||
//reject();
|
||||
@ -178,7 +180,7 @@ export class Popup {
|
||||
// Allow it to close
|
||||
}
|
||||
}
|
||||
opts = util.extend({
|
||||
opts = extend({
|
||||
showPrompt: false,
|
||||
cancel: () => {
|
||||
},
|
||||
@ -237,7 +239,7 @@ export class Popup {
|
||||
}
|
||||
}
|
||||
|
||||
opts = util.extend({
|
||||
opts = extend({
|
||||
showPrompt: true,
|
||||
promptPlaceholder: '',
|
||||
cancel: () => {
|
||||
@ -256,7 +258,7 @@ export class Popup {
|
||||
*/
|
||||
get(handle) {
|
||||
if (handle) {
|
||||
return this.ctrl.getByHandle(handle, OVERLAY_TYPE);
|
||||
return this.ctrl.getByHandle(handle);
|
||||
}
|
||||
return this.ctrl.getByType(OVERLAY_TYPE);
|
||||
}
|
||||
@ -265,34 +267,40 @@ export class Popup {
|
||||
|
||||
const OVERLAY_TYPE = 'popup';
|
||||
|
||||
|
||||
// TODO add button type to button: [type]="button.type"
|
||||
@Component({
|
||||
selector: 'ion-popup',
|
||||
template:
|
||||
'<backdrop (click)="_cancel($event)" tappable disable-activated></backdrop>' +
|
||||
'<popup-wrapper [ng-class]="cssClass">' +
|
||||
'<backdrop (click)="cancel($event)" tappable disable-activated></backdrop>' +
|
||||
'<popup-wrapper>' +
|
||||
'<div class="popup-head">' +
|
||||
'<h2 class="popup-title" [inner-html]="title" *ng-if="title"></h2>' +
|
||||
'<h3 class="popup-sub-title" [inner-html]="subTitle" *ng-if="subTitle"></h3>' +
|
||||
'<h2 class="popup-title" [inner-html]="d.title" *ng-if="d.title"></h2>' +
|
||||
'<h3 class="popup-sub-title" [inner-html]="d.subTitle" *ng-if="d.subTitle"></h3>' +
|
||||
'</div>' +
|
||||
'<div class="popup-body">' +
|
||||
'<div [inner-html]="template" *ng-if="template"></div>' +
|
||||
'<input type="{{inputType || \'text\'}}" placeholder="{{inputPlaceholder}}" *ng-if="showPrompt" class="prompt-input">' +
|
||||
'<div [inner-html]="d.template" *ng-if="d.template"></div>' +
|
||||
'<input type="{{d.inputType || \'text\'}}" placeholder="{{d.inputPlaceholder}}" *ng-if="d.showPrompt" class="prompt-input">' +
|
||||
'</div>' +
|
||||
'<div class="popup-buttons" *ng-if="buttons.length">' +
|
||||
'<button *ng-for="#button of buttons" (click)="buttonTapped(button, $event)" [inner-html]="button.text"></button>' +
|
||||
'<div class="popup-buttons" *ng-if="d.buttons.length">' +
|
||||
'<button *ng-for="#btn of d.buttons" (click)="buttonTapped(btn, $event)" [inner-html]="btn.text"></button>' +
|
||||
'</div>' +
|
||||
'</popup-wrapper>',
|
||||
'</popup-wrapper>',
|
||||
host: {
|
||||
'[style.zIndex]': '_zIndex'
|
||||
'[style.zIndex]': '_zIndex',
|
||||
'role': 'dialog'
|
||||
},
|
||||
directives: [FORM_DIRECTIVES, NgClass, NgIf, NgFor, Button]
|
||||
})
|
||||
|
||||
class PopupCmp {
|
||||
|
||||
constructor(elementRef: ElementRef) {
|
||||
constructor(elementRef: ElementRef, params: NavParams, renderer: Renderer) {
|
||||
this.elementRef = elementRef;
|
||||
this.d = params.data;
|
||||
|
||||
if (this.d.cssClass) {
|
||||
renderer.setElementClass(elementRef, this.d.cssClass, true);
|
||||
}
|
||||
}
|
||||
|
||||
onInit() {
|
||||
@ -305,90 +313,118 @@ class PopupCmp {
|
||||
});
|
||||
}
|
||||
|
||||
buttonTapped(button, event) {
|
||||
buttonTapped(button, ev) {
|
||||
let promptValue = this.promptInput && this.promptInput.value;
|
||||
|
||||
let retVal = button.onTap && button.onTap(event, this, {
|
||||
let retVal = button.onTap && button.onTap(ev, this, {
|
||||
promptValue: promptValue
|
||||
});
|
||||
|
||||
// If the event.preventDefault() wasn't called, close
|
||||
if (!event.defaultPrevented) {
|
||||
if (!ev.defaultPrevented) {
|
||||
// If this is a cancel button, reject the promise
|
||||
if (button.isCancel) {
|
||||
this.promiseReject();
|
||||
this.d.promiseReject();
|
||||
|
||||
} else {
|
||||
// Resolve with the prompt value
|
||||
this.promiseResolve(promptValue);
|
||||
this.d.promiseResolve(promptValue);
|
||||
}
|
||||
|
||||
return this.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_cancel(event) {
|
||||
this.cancel && this.cancel(event);
|
||||
cancel(ev) {
|
||||
this.d.cancel && this.d.cancel(event);
|
||||
|
||||
if (!event.defaultPrevented) {
|
||||
this.promiseReject();
|
||||
if (!ev.defaultPrevented) {
|
||||
this.d.promiseReject();
|
||||
return this.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PopupAnimation extends Animation {
|
||||
constructor(element) {
|
||||
super(element);
|
||||
this
|
||||
.easing('ease-in-out')
|
||||
.duration(200);
|
||||
|
||||
this.backdrop = new Animation(element.querySelector('backdrop'));
|
||||
this.wrapper = new Animation(element.querySelector('popup-wrapper'));
|
||||
|
||||
this.add(this.backdrop, this.wrapper);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Animations for popups
|
||||
*/
|
||||
class PopupPopIn extends PopupAnimation {
|
||||
constructor(element) {
|
||||
super(element);
|
||||
this.wrapper.fromTo('opacity', '0.01', '1')
|
||||
this.wrapper.fromTo('scale', '1.1', '1');
|
||||
class PopupPopIn extends Animation {
|
||||
constructor(enteringView, leavingView, opts) {
|
||||
super(null, opts);
|
||||
|
||||
this.backdrop.fromTo('opacity', '0', '0.3')
|
||||
let ele = enteringView.pageRef().nativeElement;
|
||||
let backdrop = new Animation(ele.querySelector('backdrop'));
|
||||
let wrapper = new Animation(ele.querySelector('popup-wrapper'));
|
||||
|
||||
wrapper.fromTo('opacity', '0.01', '1').fromTo('scale', '1.1', '1');
|
||||
backdrop.fromTo('opacity', '0.01', '0.3');
|
||||
|
||||
this
|
||||
.easing('ease-in-out')
|
||||
.duration(200)
|
||||
.add(backdrop, wrapper);
|
||||
}
|
||||
}
|
||||
Animation.register('popup-pop-in', PopupPopIn);
|
||||
|
||||
class PopupPopOut extends PopupAnimation {
|
||||
constructor(element) {
|
||||
super(element);
|
||||
this.wrapper.fromTo('opacity', '1', '0')
|
||||
this.wrapper.fromTo('scale', '1', '0.9');
|
||||
|
||||
this.backdrop.fromTo('opacity', '0.3', '0')
|
||||
class PopupPopOut extends Animation {
|
||||
constructor(enteringView, leavingView, opts) {
|
||||
super(null, opts);
|
||||
|
||||
let ele = leavingView.pageRef().nativeElement;
|
||||
let backdrop = new Animation(ele.querySelector('backdrop'));
|
||||
let wrapper = new Animation(ele.querySelector('popup-wrapper'));
|
||||
|
||||
wrapper.fromTo('opacity', '1', '0').fromTo('scale', '1', '0.9');
|
||||
backdrop.fromTo('opacity', '0.3', '0');
|
||||
|
||||
this
|
||||
.easing('ease-in-out')
|
||||
.duration(200)
|
||||
.add(backdrop, wrapper);
|
||||
}
|
||||
}
|
||||
Animation.register('popup-pop-out', PopupPopOut);
|
||||
|
||||
class PopupMdPopIn extends PopupPopIn {
|
||||
constructor(element) {
|
||||
super(element);
|
||||
this.backdrop.fromTo('opacity', '0.01', '0.5')
|
||||
|
||||
class PopupMdPopIn extends Animation {
|
||||
constructor(enteringView, leavingView, opts) {
|
||||
super(null, opts);
|
||||
|
||||
let ele = enteringView.pageRef().nativeElement;
|
||||
let backdrop = new Animation(ele.querySelector('backdrop'));
|
||||
let wrapper = new Animation(ele.querySelector('popup-wrapper'));
|
||||
|
||||
wrapper.fromTo('opacity', '0.01', '1').fromTo('scale', '1.1', '1');
|
||||
backdrop.fromTo('opacity', '0.01', '0.5');
|
||||
|
||||
this
|
||||
.easing('ease-in-out')
|
||||
.duration(200)
|
||||
.add(backdrop, wrapper);
|
||||
}
|
||||
}
|
||||
Animation.register('popup-md-pop-in', PopupMdPopIn);
|
||||
|
||||
class PopupMdPopOut extends PopupPopOut {
|
||||
constructor(element) {
|
||||
super(element);
|
||||
this.backdrop.fromTo('opacity', '0.5', '0')
|
||||
|
||||
class PopupMdPopOut extends Animation {
|
||||
constructor(enteringView, leavingView, opts) {
|
||||
super(null, opts);
|
||||
|
||||
let ele = leavingView.pageRef().nativeElement;
|
||||
let backdrop = new Animation(ele.querySelector('backdrop'));
|
||||
let wrapper = new Animation(ele.querySelector('popup-wrapper'));
|
||||
|
||||
wrapper.fromTo('opacity', '1', '0').fromTo('scale', '1', '0.9');
|
||||
backdrop.fromTo('opacity', '0.5', '0');
|
||||
|
||||
this
|
||||
.easing('ease-in-out')
|
||||
.duration(200)
|
||||
.add(backdrop, wrapper);
|
||||
}
|
||||
}
|
||||
Animation.register('popup-md-pop-out', PopupMdPopOut);
|
||||
|
@ -115,7 +115,6 @@ export class Tabs extends Ion {
|
||||
this.app = app;
|
||||
this.subPages = config.get('tabSubPages');
|
||||
|
||||
// collection of children "Tab" instances, which extends NavController
|
||||
this.tabs = [];
|
||||
|
||||
// Tabs may also be an actual ViewController which was navigated to
|
||||
|
@ -18,7 +18,7 @@ export class RippleActivator extends Activator {
|
||||
// create a new ripple element
|
||||
this.expandSpeed = EXPAND_DOWN_PLAYBACK_RATE;
|
||||
|
||||
rafFrames(2, () => {
|
||||
raf(() => {
|
||||
let clientRect = activatableEle.getBoundingClientRect();
|
||||
|
||||
raf(() => {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import {CORE_DIRECTIVES, FORM_DIRECTIVES, forwardRef} from 'angular2/angular2'
|
||||
|
||||
import {OverlayAnchor} from '../components/overlay/overlay';
|
||||
import {OverlayNav} from '../components/overlay/overlay';
|
||||
import {Menu} from '../components/menu/menu';
|
||||
import {MenuToggle} from '../components/menu/menu-toggle';
|
||||
import {MenuClose} from '../components/menu/menu-close';
|
||||
@ -42,7 +42,7 @@ export const IONIC_DIRECTIVES = [
|
||||
FORM_DIRECTIVES,
|
||||
|
||||
// Content
|
||||
OverlayAnchor,
|
||||
OverlayNav,
|
||||
Menu,
|
||||
MenuToggle,
|
||||
MenuClose,
|
||||
|
@ -21,7 +21,7 @@ Config.setModeConfig('ios', {
|
||||
modalEnter: 'modal-slide-in',
|
||||
modalLeave: 'modal-slide-out',
|
||||
|
||||
pageTransition: 'ios',
|
||||
pageTransition: 'ios-transition',
|
||||
pageTransitionDelay: 16,
|
||||
|
||||
popupEnter: 'popup-pop-in',
|
||||
@ -50,7 +50,7 @@ Config.setModeConfig('md', {
|
||||
modalEnter: 'modal-md-slide-in',
|
||||
modalLeave: 'modal-md-slide-out',
|
||||
|
||||
pageTransition: 'md',
|
||||
pageTransition: 'md-transition',
|
||||
pageTransitionDelay: 120,
|
||||
|
||||
popupEnter: 'popup-md-pop-in',
|
||||
|
@ -16,10 +16,8 @@ export * from './util/events'
|
||||
|
||||
export * from './animations/animation'
|
||||
export * from './animations/builtins'
|
||||
|
||||
export * from './transitions/transition'
|
||||
export * from './transitions/ios-transition'
|
||||
export * from './transitions/md-transition'
|
||||
export * from './animations/ios-transition'
|
||||
export * from './animations/md-transition'
|
||||
|
||||
export * from './translation/translate'
|
||||
export * from './translation/translate_pipe'
|
||||
|
@ -1,22 +0,0 @@
|
||||
|
||||
|
||||
export class Transition {
|
||||
|
||||
static create(navCtrl, opts = {}) {
|
||||
const name = opts.animation || 'ios';
|
||||
|
||||
let TransitionClass = transitionRegistry[name];
|
||||
if (!TransitionClass) {
|
||||
TransitionClass = transitionRegistry.ios;
|
||||
}
|
||||
|
||||
return new TransitionClass(navCtrl, opts);
|
||||
}
|
||||
|
||||
static register(name, TransitionClass) {
|
||||
transitionRegistry[name] = TransitionClass;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let transitionRegistry = {};
|
@ -118,24 +118,6 @@ export function nextUid() {
|
||||
return ++uid;
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple logger class.
|
||||
*/
|
||||
export class Log {
|
||||
static log(...args) {
|
||||
console.log.apply(console, args);
|
||||
}
|
||||
static info(...args) {
|
||||
console.info.apply(console, args);
|
||||
}
|
||||
static warn(...args) {
|
||||
console.warn.apply(console, args);
|
||||
}
|
||||
static error(...args) {
|
||||
console.error.apply(console, args);
|
||||
}
|
||||
}
|
||||
|
||||
export const array = {
|
||||
find(arr, cb) {
|
||||
for (let i = 0, ii = arr.length; i < ii; i++) {
|
||||
|
@ -1,17 +1,15 @@
|
||||
import {FormBuilder, Validators} from 'angular2/angular2';
|
||||
import {Log} from 'ionic/util'
|
||||
import {Page, NavController} from 'ionic/ionic'
|
||||
|
||||
|
||||
@Page({
|
||||
templateUrl: 'app/<%= fileName %>/<%= fileName %>.html'
|
||||
})
|
||||
class <%= jsClassName %> {
|
||||
constructor(nav: NavController ) {
|
||||
this.nav = nav;
|
||||
|
||||
this.nav = nav
|
||||
Log.log('LOGIN PAGE', this)
|
||||
|
||||
var fb = new FormBuilder()
|
||||
var fb = new FormBuilder();
|
||||
|
||||
this.loginForm = fb.group({
|
||||
email: ['', Validators.required],
|
||||
@ -20,13 +18,12 @@ class <%= jsClassName %> {
|
||||
|
||||
}
|
||||
|
||||
doLogin(event) {
|
||||
Log.log('Doing login')
|
||||
event.preventDefault();
|
||||
doLogin() {
|
||||
console.log(this.loginForm.value);
|
||||
}
|
||||
|
||||
doSignup(event) {
|
||||
doSignup() {
|
||||
this.nav.push(SignupPage)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
import {FormBuilder, Validators} from 'angular2/angular2';
|
||||
import {Log} from 'ionic/util'
|
||||
import {Page, NavController} from 'ionic/ionic'
|
||||
import {Page, NavController} from 'ionic/ionic';
|
||||
|
||||
|
||||
@Page({
|
||||
@ -8,11 +7,9 @@ import {Page, NavController} from 'ionic/ionic'
|
||||
})
|
||||
export class <%= jsClassName %> {
|
||||
constructor(nav: NavController) {
|
||||
this.nav = nav
|
||||
this.nav = nav;
|
||||
|
||||
Log.log('SIGNUP PAGE')
|
||||
|
||||
var fb = new FormBuilder()
|
||||
var fb = new FormBuilder();
|
||||
|
||||
this.signupForm = fb.group({
|
||||
name: ['', Validators.required],
|
||||
@ -21,14 +18,14 @@ export class <%= jsClassName %> {
|
||||
});
|
||||
}
|
||||
|
||||
doLogin(event) {
|
||||
doLogin() {
|
||||
this.nav.pop()
|
||||
}
|
||||
doSignup(event) {
|
||||
Log.log('Doing signup')
|
||||
event.preventDefault();
|
||||
|
||||
doSignup() {
|
||||
console.log(this.signupForm.value);
|
||||
|
||||
this.nav.push(AppPage)
|
||||
this.nav.push(AppPage);
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user