Files
ionic-framework/ionic/components/overlay/overlay-controller.ts
Adam Bradley cd319e1cf2 working modals
2015-10-05 11:05:55 -05:00

158 lines
3.8 KiB
TypeScript

import {Component, View, NgZone, Injectable, Renderer} from 'angular2/angular2';
import {IonicApp} from '../app/app';
import {Animation} from '../../animations/animation';
import * as util from 'ionic/util';
@Injectable()
export class OverlayController {
constructor(app: IonicApp, zone: NgZone, renderer: Renderer) {
this.app = app;
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);
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();
}
ref._z = ROOT_Z_INDEX;
for (let i = 0; i < this.refs.length; i++) {
if (this.refs[i]._z >= ref._z) {
ref._z = this.refs[i]._z + 1;
}
}
this.renderer.setElementStyle(ref.location, 'zIndex', ref._z);
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));
};
instance.onViewLoaded && instance.onViewLoaded();
instance.onViewWillEnter && instance.onViewWillEnter();
let animation = Animation.create(ref.location.nativeElement, opts.enterAnimation);
animation.before.addClass('show-overlay');
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.onViewDidEnter && instance.onViewDidEnter();
resolve();
});
});
});
}).catch(err => {
console.error(err);
});
} catch (e) {
console.error(e);
}
return promise;
}
close(ref, opts) {
let resolve;
let promise = new Promise(res => { resolve = res; });
let instance = ref.instance;
instance.onViewWillLeave && instance.onViewWillLeave();
instance.onViewWillUnload && instance.onViewWillUnload();
let animation = Animation.create(ref.location.nativeElement, opts.leaveAnimation);
animation.after.removeClass('show-overlay');
this.app.setEnabled(false, animation.duration());
this.app.setTransitioning(true, animation.duration());
this.zone.runOutsideAngular(() => {
animation.play().then(() => {
animation.dispose();
this.zone.run(() => {
instance.onViewDidLeave && instance.onViewDidLeave();
instance.onViewDidUnload && instance.onViewDidUnload();
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;
}
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;
}
}
const ROOT_Z_INDEX = 1000;