mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
refactor(): rename ViewController/ViewItem
Rename ViewController to NavController, ViewItem to ViewController
This commit is contained in:
@@ -20,6 +20,7 @@ export * from 'ionic/components/show-hide-when/show-hide-when'
|
||||
export * from 'ionic/components/modal/modal'
|
||||
export * from 'ionic/components/nav/nav'
|
||||
export * from 'ionic/components/nav/nav-controller'
|
||||
export * from 'ionic/components/nav/view-controller'
|
||||
export * from 'ionic/components/nav/nav-push'
|
||||
export * from 'ionic/components/nav/nav-router'
|
||||
export * from 'ionic/components/nav-bar/nav-bar'
|
||||
@@ -34,4 +35,3 @@ export * from 'ionic/components/switch/switch'
|
||||
export * from 'ionic/components/tabs/tabs'
|
||||
export * from 'ionic/components/tabs/tab'
|
||||
export * from 'ionic/components/toolbar/toolbar'
|
||||
export * from 'ionic/components/view/view-item'
|
||||
|
||||
@@ -130,6 +130,20 @@ ion-pane {
|
||||
order: $flex-order-view-content;
|
||||
}
|
||||
|
||||
ion-view {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
|
||||
background-color: white;
|
||||
|
||||
transform: translateZ(0px);
|
||||
}
|
||||
|
||||
[hidden],
|
||||
template,
|
||||
root-anchor {
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
@Decorator({
|
||||
selector: 'ion-primary-options'
|
||||
})
|
||||
export class ItemPrimaryOptions {
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
@Decorator({
|
||||
selector: 'ion-secondary-options'
|
||||
})
|
||||
export class ItemSecondaryOptions {
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
import {ElementRef, Host, Directive} from 'angular2/angular2';
|
||||
|
||||
import {Item} from 'ionic/components/item/item';
|
||||
import {SlideGesture} from 'ionic/gestures/slide-gesture';
|
||||
|
||||
/**
|
||||
* @name ionPrimarySwipeButtons
|
||||
* @description
|
||||
* Creates a swipeable button inside a list item, that is visible when the item is swiped to the left by the user. Swiped open buttons can be hidden with `setOpen(false)`.
|
||||
*
|
||||
* @usage
|
||||
* TODO
|
||||
*/
|
||||
@Directive({
|
||||
selector: 'ion-primary-swipe-buttons'
|
||||
})
|
||||
export class ItemPrimarySwipeButtons {
|
||||
/**
|
||||
* @param {ElementRef} elementRef A reference to the component's DOM element.
|
||||
* @param {Item} item The list item containing the swipeable buttons.
|
||||
*/
|
||||
constructor(
|
||||
elementRef: ElementRef,
|
||||
@Host() item: Item
|
||||
) {
|
||||
item.primarySwipeButtons = this;
|
||||
this.ele = elementRef.nativeElement;
|
||||
this.item = item;
|
||||
this.gesture = new ItemSlideGesture(this);
|
||||
this.gesture.listen();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {boolean} isOpen Whether or not the button should be set to open/visible.
|
||||
*/
|
||||
setOpen(isOpen) {
|
||||
if (isOpen !== this.isOpen) {
|
||||
this.isOpen = isOpen;
|
||||
requestAnimationFrame(() => {
|
||||
this.ele.classList[isOpen?'add':'remove'](isOpen);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
@Directive({
|
||||
selector: 'ion-secondary-swipe-buttons'
|
||||
})
|
||||
export class ItemSecondarySwipeButtons {
|
||||
}
|
||||
|
||||
class ItemSlideGesture extends SlideGesture {
|
||||
constructor(buttons) {
|
||||
super(buttons.item.ele)
|
||||
this.buttons = buttons
|
||||
}
|
||||
|
||||
getSlideBoundaries() {
|
||||
return {
|
||||
min: -this.buttons.ele.offsetWidth,
|
||||
max: 0,
|
||||
};
|
||||
}
|
||||
|
||||
getElementStartPos(slide, ev) {
|
||||
return this.buttons.isOpen ? slide.max : slide.min;
|
||||
}
|
||||
|
||||
onSlideBeforeStart() {
|
||||
this.buttons.ele.classList.add('changing')
|
||||
this.buttons.ele.classList.add('no-transition')
|
||||
return new Promise(resolve => {
|
||||
requestAnimationFrame(resolve)
|
||||
})
|
||||
}
|
||||
onSlide(slide, ev) {
|
||||
this.buttons.ele.style.transform = 'translate3d(' + slide.distance + 'px,0,0)';
|
||||
}
|
||||
onSlideEnd(slide, ev) {
|
||||
this.buttons.ele.style.transform = ''
|
||||
this.buttons.ele.classList.remove('no-transition')
|
||||
if (Math.abs(ev.velocityX) > 0.2 || Math.abs(slide.delta) > Math.abs(slide.max) * 0.5) {
|
||||
this.buttons.setOpen(!this.buttons.isOpen);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
import {Component, Directive, View, ElementRef, NgIf, ViewQuery, QueryList} from 'angular2/angular2';
|
||||
|
||||
import {ItemPrimaryOptions, ItemSecondaryOptions} from './item-options';
|
||||
import {ItemPrimarySwipeButtons, ItemSecondarySwipeButtons} from './item-swipe-buttons';
|
||||
import {dom} from 'ionic/util';
|
||||
|
||||
|
||||
/**
|
||||
* @name ionItem
|
||||
* @description
|
||||
|
||||
@@ -2,7 +2,7 @@ import {Directive, ElementRef, Optional} from 'angular2/angular2';
|
||||
|
||||
import {Ion} from '../ion';
|
||||
import {IonicApp} from '../app/app';
|
||||
import {ViewItem} from '../view/view-item';
|
||||
import {ViewController} from '../nav/view-controller';
|
||||
import {Navbar} from '../nav-bar/nav-bar';
|
||||
|
||||
|
||||
@@ -24,12 +24,12 @@ export class MenuToggle extends Ion {
|
||||
constructor(
|
||||
app: IonicApp,
|
||||
elementRef: ElementRef,
|
||||
@Optional() item: ViewItem,
|
||||
@Optional() viewCtrl: ViewController,
|
||||
@Optional() navbar: Navbar
|
||||
) {
|
||||
super(elementRef, null);
|
||||
this.app = app;
|
||||
this.item = item;
|
||||
this.viewCtrl = viewCtrl;
|
||||
this.withinNavbar = !!navbar;
|
||||
}
|
||||
|
||||
@@ -45,8 +45,8 @@ export class MenuToggle extends Ion {
|
||||
}
|
||||
|
||||
get isHidden() {
|
||||
if (this.withinNavbar && this.item) {
|
||||
return !this.item.isRoot();
|
||||
if (this.withinNavbar && this.viewCtrl) {
|
||||
return !this.viewCtrl.isRoot();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@ import {ToolbarBase} from '../toolbar/toolbar';
|
||||
import {IonicConfig} from '../../config/config';
|
||||
import {IonicView} from '../../config/decorators';
|
||||
import {IonicApp} from '../app/app';
|
||||
import {ViewItem} from '../view/view-item';
|
||||
import {ViewController} from '../view/view-controller';
|
||||
import {ViewController} from '../nav/view-controller';
|
||||
import {NavController} from '../nav/nav-controller';
|
||||
|
||||
|
||||
@Directive({
|
||||
@@ -17,19 +17,19 @@ import {ViewController} from '../view/view-controller';
|
||||
})
|
||||
class BackButton extends Ion {
|
||||
constructor(
|
||||
@Optional() viewCtrl: ViewController,
|
||||
@Optional() navCtrl: NavController,
|
||||
elementRef: ElementRef,
|
||||
@Optional() @Inject(forwardRef(() => Navbar)) navbar: Navbar
|
||||
) {
|
||||
super(elementRef, null);
|
||||
this.viewCtrl = viewCtrl;
|
||||
this.navCtrl = navCtrl;
|
||||
navbar && navbar.setBackButtonRef(elementRef);
|
||||
}
|
||||
|
||||
goBack(ev) {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
this.viewCtrl && this.viewCtrl.pop();
|
||||
this.navCtrl && this.navCtrl.pop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,14 +73,14 @@ class BackButtonText extends Ion {
|
||||
export class Navbar extends ToolbarBase {
|
||||
constructor(
|
||||
app: IonicApp,
|
||||
@Optional() item: ViewItem,
|
||||
@Optional() viewCtrl: ViewController,
|
||||
elementRef: ElementRef,
|
||||
config: IonicConfig
|
||||
) {
|
||||
super(elementRef, config);
|
||||
|
||||
this.app = app;
|
||||
item && item.navbarView(this);
|
||||
viewCtrl && viewCtrl.navbarView(this);
|
||||
|
||||
this.bbIcon = config.setting('backButtonIcon');
|
||||
this.bbDefault = config.setting('backButtonText');
|
||||
@@ -119,9 +119,9 @@ export class Navbar extends ToolbarBase {
|
||||
})
|
||||
export class NavbarTemplate {
|
||||
constructor(
|
||||
@Optional() item: ViewItem,
|
||||
@Optional() viewCtrl: ViewController,
|
||||
@Optional() templateRef: TemplateRef
|
||||
) {
|
||||
item && item.addTemplateRef('navbar', templateRef);
|
||||
viewCtrl && viewCtrl.addTemplateRef('navbar', templateRef);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import {Component, View, Directive, Host, ElementRef, forwardRef, Inject} from '
|
||||
import {ViewContainerRef} from 'angular2/src/core/compiler/view_container_ref';
|
||||
|
||||
import {Pane} from './pane';
|
||||
import {ViewController} from '../view/view-controller';
|
||||
import {NavController} from './nav-controller';
|
||||
|
||||
|
||||
@Directive({selector: 'template[pane-anchor]'})
|
||||
@@ -32,10 +32,10 @@ export class PaneContentAnchor {
|
||||
})
|
||||
class NavBarAnchor {
|
||||
constructor(
|
||||
@Inject(forwardRef(() => ViewController)) viewCtrl: ViewController,
|
||||
@Inject(forwardRef(() => NavController)) navCtrl: NavController,
|
||||
viewContainerRef: ViewContainerRef
|
||||
) {
|
||||
viewCtrl.navbarViewContainer(viewContainerRef);
|
||||
navCtrl.navbarViewContainer(viewContainerRef);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,51 +1,783 @@
|
||||
import {extend} from '../../util/util';
|
||||
import {Compiler, ElementRef, Injector, bind, NgZone} from 'angular2/angular2';
|
||||
import {DynamicComponentLoader} from 'angular2/src/core/compiler/dynamic_component_loader';
|
||||
import {AppViewManager} from 'angular2/src/core/compiler/view_manager';
|
||||
|
||||
import {Ion} from '../ion';
|
||||
import {IonicConfig} from '../../config/config';
|
||||
import {IonicApp} from '../app/app';
|
||||
import {ViewController} from './view-controller';
|
||||
import {PaneController} from './pane';
|
||||
import {Transition} from '../../transitions/transition';
|
||||
import {SwipeBackGesture} from './swipe-back';
|
||||
import * as util from 'ionic/util';
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
export class NavController {
|
||||
export class NavController extends Ion {
|
||||
|
||||
constructor(
|
||||
parentnavCtrl: NavController,
|
||||
injector: Injector,
|
||||
elementRef: ElementRef,
|
||||
zone: NgZone
|
||||
) {
|
||||
let config = injector.get(IonicConfig);
|
||||
super(elementRef, config);
|
||||
|
||||
this.parent = parentnavCtrl;
|
||||
|
||||
this.compiler = injector.get(Compiler);
|
||||
this.loader = injector.get(DynamicComponentLoader);
|
||||
this.viewMngr = injector.get(AppViewManager);
|
||||
this.app = injector.get(IonicApp);
|
||||
this.config = config;
|
||||
this.zone = zone;
|
||||
|
||||
this.views = [];
|
||||
this.panes = new PaneController(this);
|
||||
|
||||
this._sbTrans = null;
|
||||
this.sbEnabled = config.setting('swipeBackEnabled') || false;
|
||||
this.sbThreshold = config.setting('swipeBackThreshold') || 40
|
||||
|
||||
this.id = ++ctrlIds;
|
||||
this._ids = -1;
|
||||
this.zIndexes = -1;
|
||||
|
||||
// build a new injector for child ViewControllers to use
|
||||
this.bindings = Injector.resolve([
|
||||
bind(NavController).toValue(this)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} nav TODO
|
||||
* @param {TODO} componentType TODO
|
||||
* @param {TODO} [params={}] TODO
|
||||
* @param {TODO} [opts={}] TODO
|
||||
* @returns {Promise} TODO
|
||||
*/
|
||||
constructor(nav) {
|
||||
this._nav = nav;
|
||||
push(componentType, params = {}, opts = {}) {
|
||||
if (!componentType) {
|
||||
return Promise.reject();
|
||||
}
|
||||
if (typeof componentType !== 'function') {
|
||||
throw 'Loading component must be a component class, not "' + componentType.toString() + '"';
|
||||
}
|
||||
|
||||
let resolve;
|
||||
let promise = new Promise(res => { resolve = res; });
|
||||
|
||||
// do not animate if this is the first in the stack
|
||||
if (!this.views.length) {
|
||||
opts.animation = 'none';
|
||||
}
|
||||
|
||||
// default the direction to "forward"
|
||||
opts.direction = opts.direction || 'forward';
|
||||
|
||||
// the active view is going to be the leaving one (if one exists)
|
||||
let leavingView = this.getActive() || new ViewController();
|
||||
leavingView.shouldCache = (util.isBoolean(opts.cacheleavingView) ? opts.cacheleavingView : true);
|
||||
leavingView.shouldDestroy = !leavingView.shouldCache;
|
||||
if (leavingView.shouldDestroy) {
|
||||
leavingView.willUnload();
|
||||
}
|
||||
|
||||
// create a new ViewController
|
||||
let enteringView = new ViewController(this, componentType, params);
|
||||
|
||||
// add the view to the stack
|
||||
this.add(enteringView);
|
||||
|
||||
if (this.router) {
|
||||
// notify router of the state change
|
||||
this.router.stateChange('push', enteringView, params);
|
||||
}
|
||||
|
||||
// start the transition
|
||||
this.transition(enteringView, leavingView, opts, () => {
|
||||
resolve();
|
||||
});
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the history stack to match the list of component items.
|
||||
* @param {TODO} items TODO
|
||||
* @return {TODO} TODO
|
||||
* TODO
|
||||
* @param {TODO} [opts={}] TODO
|
||||
* @returns {Promise} TODO
|
||||
*/
|
||||
setItems(items) {
|
||||
return this._nav.setItems(items);
|
||||
pop(opts = {}) {
|
||||
if (!this.canGoBack()) {
|
||||
return Promise.reject();
|
||||
}
|
||||
|
||||
let resolve;
|
||||
let promise = new Promise(res => { resolve = res; });
|
||||
|
||||
// default the direction to "back"
|
||||
opts.direction = opts.direction || 'back';
|
||||
|
||||
// get the active view and set that it is staged to be leaving
|
||||
// was probably the one popped from the stack
|
||||
let leavingView = this.getActive() || new ViewController();
|
||||
leavingView.shouldCache = (util.isBoolean(opts.cacheleavingView) ? opts.cacheleavingView : false);
|
||||
leavingView.shouldDestroy = !leavingView.shouldCache;
|
||||
if (leavingView.shouldDestroy) {
|
||||
leavingView.willUnload();
|
||||
}
|
||||
|
||||
// the entering view is now the new last view
|
||||
// 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, () => {
|
||||
// transition completed, destroy the leaving view
|
||||
resolve();
|
||||
});
|
||||
|
||||
} else {
|
||||
this._transComplete();
|
||||
resolve();
|
||||
}
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the history stack.
|
||||
* @return {TODO} TODO
|
||||
* Set the view stack to reflect the given component classes.
|
||||
* @param {TODO} components TODO
|
||||
* @param {TODO} [opts={}] TODO
|
||||
* @returns {Promise} TODO
|
||||
*/
|
||||
clear() {
|
||||
return this._nav.clear();
|
||||
setViews(components, opts = {}) {
|
||||
if (!components || !components.length) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
// if animate has not been set then default to false
|
||||
opts.animate = opts.animate || false;
|
||||
|
||||
// ensure leaving views are not cached, and should be destroyed
|
||||
opts.cacheleavingView = false;
|
||||
|
||||
// get the views to auto remove without having to do a transiton for each
|
||||
// the last view (the currently active one) will do a normal transition out
|
||||
if (this.views.length > 1) {
|
||||
let autoRemoveItems = this.views.slice(0, this.views.length - 1);
|
||||
for (let i = 0; i < autoRemoveItems.length; i++) {
|
||||
autoRemoveItems[i].shouldDestroy = true;
|
||||
autoRemoveItems[i].shouldCache = false;
|
||||
autoRemoveItems[i].willUnload();
|
||||
}
|
||||
}
|
||||
|
||||
let componentObj = null;
|
||||
let componentType = null;
|
||||
let viewCtrl = null;
|
||||
|
||||
// create the ViewControllers that go before the new active ViewController in the stack
|
||||
// but the previous views won't should render yet
|
||||
if (components.length > 1) {
|
||||
let newBeforeItems = components.slice(0, components.length - 1);
|
||||
for (let j = 0; j < newBeforeItems.length; j++) {
|
||||
componentObj = newBeforeItems[j];
|
||||
|
||||
if (componentObj) {
|
||||
|
||||
// could be an object with a componentType property, or it is a componentType
|
||||
componentType = componentObj.componentType || componentObj;
|
||||
|
||||
viewCtrl = new ViewController(this, componentType, componentObj.params);
|
||||
viewCtrl.state = CACHED_STATE;
|
||||
viewCtrl.shouldDestroy = false;
|
||||
viewCtrl.shouldCache = false;
|
||||
|
||||
// add the item to the stack
|
||||
this.add(viewCtrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get the component that will become the active item
|
||||
// it'll be the last one in the given components array
|
||||
componentObj = components[ components.length - 1 ];
|
||||
componentType = componentObj.componentType || componentObj;
|
||||
|
||||
// transition the leaving and entering
|
||||
return this.push(componentType, componentObj.params, opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Push a new component onto the history stack.
|
||||
* @return {TODO} TODO
|
||||
* TODO
|
||||
* @param {TODO} componentType TODO
|
||||
* @param {TODO} [params={}] TODO
|
||||
* @param {TODO} [opts={}] TODO
|
||||
* @returns {Promise} TODO
|
||||
*/
|
||||
push() {
|
||||
return this._nav.push.apply(this._nav, arguments);
|
||||
setRoot(componentType, params = {}, opts = {}) {
|
||||
return this.setViews([{
|
||||
componentType,
|
||||
params
|
||||
}], opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pop the top most (visible) component off the history stack.
|
||||
* @return {TODO} TODO
|
||||
* TODO
|
||||
* @param {TODO} enteringView TODO
|
||||
* @param {TODO} leavingView TODO
|
||||
* @param {TODO} opts TODO
|
||||
* @param {Function} callback TODO
|
||||
* @returns {any} TODO
|
||||
*/
|
||||
pop() {
|
||||
return this._nav.pop.apply(this._nav, arguments);
|
||||
transition(enteringView, leavingView, opts, callback) {
|
||||
if (!enteringView || enteringView === leavingView) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
if (opts.animate === false) {
|
||||
opts.animation = 'none';
|
||||
|
||||
} else if (!opts.animation) {
|
||||
opts.animation = this.config.setting('viewTransition');
|
||||
}
|
||||
|
||||
opts.animate = (opts.animation !== 'none');
|
||||
|
||||
// wait for the new view to complete setup
|
||||
enteringView.stage(() => {
|
||||
|
||||
this.zone.runOutsideAngular(() => {
|
||||
|
||||
enteringView.shouldDestroy = false;
|
||||
enteringView.shouldCache = false;
|
||||
enteringView.willEnter();
|
||||
leavingView.willLeave();
|
||||
|
||||
// set that the new view pushed on the stack is staged to be entering/leaving
|
||||
// staged state is important for the transition to find the correct view
|
||||
enteringView.state = STAGED_ENTERING_STATE;
|
||||
leavingView.state = STAGED_LEAVING_STATE;
|
||||
|
||||
// init the transition animation
|
||||
let transAnimation = Transition.create(this, opts);
|
||||
if (!opts.animate) {
|
||||
// force it to not animate the elements, just apply the "to" styles
|
||||
transAnimation.duration(0);
|
||||
}
|
||||
|
||||
let duration = transAnimation.duration();
|
||||
if (duration > 64) {
|
||||
// block any clicks during the transition and provide a
|
||||
// fallback to remove the clickblock if something goes wrong
|
||||
this.app.setEnabled(false, duration);
|
||||
}
|
||||
|
||||
// start the transition
|
||||
transAnimation.play().then(() => {
|
||||
|
||||
// transition has completed, update each view's state
|
||||
enteringView.state = ACTIVE_STATE;
|
||||
leavingView.state = CACHED_STATE;
|
||||
|
||||
// dispose any views that shouldn't stay around
|
||||
transAnimation.dispose();
|
||||
|
||||
enteringView.didEnter();
|
||||
leavingView.didLeave();
|
||||
|
||||
// all done!
|
||||
this.zone.run(() => {
|
||||
this._transComplete();
|
||||
callback();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
swipeBackStart() {
|
||||
if (!this.app.isEnabled() || !this.canSwipeBack()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// disables the app during the transition
|
||||
this.app.setEnabled(false);
|
||||
|
||||
// default the direction to "back"
|
||||
let opts = {
|
||||
direction: 'back'
|
||||
};
|
||||
|
||||
// get the active view and set that it is staged to be leaving
|
||||
// was probably the one popped from the stack
|
||||
let leavingView = this.getActive() || new ViewController();
|
||||
leavingView.shouldDestroy = true;
|
||||
leavingView.shouldCache = false;
|
||||
leavingView.willLeave();
|
||||
leavingView.willUnload();
|
||||
|
||||
// the entering view is now the new last view
|
||||
let enteringView = this.getPrevious(leavingView);
|
||||
enteringView.shouldDestroy = false;
|
||||
enteringView.shouldCache = false;
|
||||
enteringView.willEnter();
|
||||
|
||||
// wait for the new view to complete setup
|
||||
enteringView.stage(() => {
|
||||
|
||||
this.zone.runOutsideAngular(() => {
|
||||
// set that the new view pushed on the stack is staged to be entering/leaving
|
||||
// staged state is important for the transition to find the correct view
|
||||
enteringView.state = STAGED_ENTERING_STATE;
|
||||
leavingView.state = STAGED_LEAVING_STATE;
|
||||
|
||||
// init the swipe back transition animation
|
||||
this._sbTrans = Transition.create(this, opts);
|
||||
this._sbTrans.easing('linear').progressStart();
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} progress TODO
|
||||
*/
|
||||
swipeBackProgress(value) {
|
||||
if (this._sbTrans) {
|
||||
// continue to disable the app while actively dragging
|
||||
this.app.setEnabled(false, 4000);
|
||||
|
||||
// set the transition animation's progress
|
||||
this._sbTrans.progress(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {TODO} completeSwipeBack Should the swipe back complete or not.
|
||||
* @param {number} rate How fast it closes
|
||||
*/
|
||||
swipeBackEnd(completeSwipeBack, rate) {
|
||||
if (!this._sbTrans) return;
|
||||
|
||||
// disables the app during the transition
|
||||
this.app.setEnabled(false);
|
||||
|
||||
this._sbTrans.progressEnd(completeSwipeBack, rate).then(() => {
|
||||
|
||||
this.zone.run(() => {
|
||||
// find the views that were entering and leaving
|
||||
let enteringView = this.getStagedenteringView();
|
||||
let leavingView = this.getStagedleavingView();
|
||||
|
||||
if (enteringView && leavingView) {
|
||||
// finish up the animation
|
||||
|
||||
if (completeSwipeBack) {
|
||||
// swipe back has completed navigating back
|
||||
// update each view's state
|
||||
enteringView.state = ACTIVE_STATE;
|
||||
leavingView.state = CACHED_STATE;
|
||||
|
||||
enteringView.didEnter();
|
||||
leavingView.didLeave();
|
||||
|
||||
if (this.router) {
|
||||
// notify router of the pop state change
|
||||
this.router.stateChange('pop', enteringView);
|
||||
}
|
||||
|
||||
} else {
|
||||
// cancelled the swipe back, they didn't end up going back
|
||||
// return views to their original state
|
||||
leavingView.state = ACTIVE_STATE;
|
||||
enteringView.state = CACHED_STATE;
|
||||
|
||||
leavingView.willEnter();
|
||||
leavingView.didEnter();
|
||||
enteringView.didLeave();
|
||||
|
||||
leavingView.shouldDestroy = false;
|
||||
enteringView.shouldDestroy = false;
|
||||
}
|
||||
}
|
||||
|
||||
// empty out and dispose the swipe back transition animation
|
||||
this._sbTrans && this._sbTrans.dispose();
|
||||
this._sbTrans = null;
|
||||
|
||||
// all done!
|
||||
this._transComplete();
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
_runSwipeBack() {
|
||||
if (this.canSwipeBack()) {
|
||||
// it is possible to swipe back
|
||||
|
||||
if (this.sbGesture) {
|
||||
// this is already an active gesture, don't create another one
|
||||
return;
|
||||
}
|
||||
|
||||
let opts = {
|
||||
edge: 'left',
|
||||
threshold: this.sbThreshold
|
||||
};
|
||||
this.sbGesture = new SwipeBackGesture(this.getNativeElement(), opts, this);
|
||||
console.debug('SwipeBackGesture listen');
|
||||
this.sbGesture.listen();
|
||||
|
||||
|
||||
} else if (this.sbGesture) {
|
||||
// it is not possible to swipe back and there is an
|
||||
// active sbGesture, so unlisten it
|
||||
console.debug('SwipeBackGesture unlisten');
|
||||
this.sbGesture.unlisten();
|
||||
this.sbGesture = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} val TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
isSwipeBackEnabled(val) {
|
||||
if (arguments.length) {
|
||||
this.sbEnabled = !!val;
|
||||
}
|
||||
return this.sbEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* If it's possible to use swipe back or not. If it's not possible
|
||||
* to go back, or swipe back is not enable then this will return false.
|
||||
* If it is possible to go back, and swipe back is enabled, then this
|
||||
* will return true.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
canSwipeBack() {
|
||||
return (this.sbEnabled && this.canGoBack());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if there's a valid previous view that we can pop back to.
|
||||
* Otherwise returns false.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
canGoBack() {
|
||||
let activeView = this.getActive();
|
||||
if (activeView) {
|
||||
return activeView.enableBack();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_transComplete() {
|
||||
let destroys = [];
|
||||
|
||||
this.views.forEach(view => {
|
||||
if (view) {
|
||||
if (view.shouldDestroy) {
|
||||
destroys.push(view);
|
||||
|
||||
} else if (view.state === CACHED_STATE && view.shouldCache) {
|
||||
view.shouldCache = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
destroys.forEach(view => {
|
||||
this.remove(view);
|
||||
view.destroy();
|
||||
});
|
||||
|
||||
// allow clicks again, but still set an enable time
|
||||
// meaning nothing with this view controller can happen for XXms
|
||||
this.app.setEnabled(true);
|
||||
|
||||
if (this.views.length === 1) {
|
||||
this.elementRef.nativeElement.classList.add('has-views');
|
||||
}
|
||||
|
||||
this._runSwipeBack();
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
getActive() {
|
||||
for (let i = 0, ii = this.views.length; i < ii; i++) {
|
||||
if (this.views[i].state === ACTIVE_STATE) {
|
||||
return this.views[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} instance TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
getByInstance(instance) {
|
||||
if (instance) {
|
||||
for (let i = 0, ii = this.views.length; i < ii; i++) {
|
||||
if (this.views[i].instance === instance) {
|
||||
return this.views[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} index TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
getByIndex(index) {
|
||||
if (index < this.views.length && index > -1) {
|
||||
return this.views[index];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} view TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
getPrevious(view) {
|
||||
if (view) {
|
||||
return this.views[ this.views.indexOf(view) - 1 ];
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} nbContainer TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
navbarViewContainer(nbContainer) {
|
||||
if (nbContainer) {
|
||||
this._nbContainer = nbContainer;
|
||||
}
|
||||
if (this._nbContainer) {
|
||||
return this._nbContainer;
|
||||
}
|
||||
if (this.parent) {
|
||||
return this.parent.navbarViewContainer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
anchorElementRef() {
|
||||
if (arguments.length) {
|
||||
this._anchorER = arguments[0];
|
||||
}
|
||||
return this._anchorER;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
anchorViewContainerRef() {
|
||||
if (arguments.length) {
|
||||
this._anchorVC = arguments[0];
|
||||
}
|
||||
return this._anchorVC;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
childNavbar() {
|
||||
if (arguments.length) {
|
||||
this._childNavbar = arguments[0];
|
||||
}
|
||||
return this._childNavbar;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} view TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
add(view) {
|
||||
view.id = this.id + '-' + (++this._ids);
|
||||
this.views.push(view);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} viewOrIndex TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
remove(viewOrIndex) {
|
||||
util.array.remove(this.views, viewOrIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* First view in this nav controller's stack. This would
|
||||
* not return an view which is about to be destroyed.
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
first() {
|
||||
for (let i = 0, l = this.views.length; i < l; i++) {
|
||||
if (!this.views[i].shouldDestroy) {
|
||||
return this.views[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Last view in this nav controller's stack. This would
|
||||
* not return an view which is about to be destroyed.
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
last() {
|
||||
for (let i = this.views.length - 1; i >= 0; i--) {
|
||||
if (!this.views[i].shouldDestroy) {
|
||||
return this.views[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} view TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
indexOf(view) {
|
||||
return this.views.indexOf(view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of sibling views in the nav controller. This does
|
||||
* not include views which are about to be destroyed.
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
length() {
|
||||
let len = 0;
|
||||
for (let i = 0, l = this.views.length; i < l; i++) {
|
||||
if (!this.views[i].shouldDestroy) {
|
||||
len++;
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} router TODO
|
||||
*/
|
||||
registerRouter(router) {
|
||||
this.router = router;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const ACTIVE_STATE = 1;
|
||||
const CACHED_STATE = 2;
|
||||
const STAGED_ENTERING_STATE = 3;
|
||||
const STAGED_LEAVING_STATE = 4;
|
||||
|
||||
let ctrlIds = -1;
|
||||
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
|
||||
@@ -29,12 +29,12 @@ export class NavRouter extends RouterOutlet {
|
||||
nav: Nav) {
|
||||
super(_elementRef, _loader, _parentRouter, nameAttr);
|
||||
|
||||
// Nav is Ionic's ViewController, which we injected into this class
|
||||
// Nav is Ionic's NavController, which we injected into this class
|
||||
this.nav = nav;
|
||||
|
||||
// register this router with Ionic's ViewController
|
||||
// Ionic's ViewController will call this NavRouter's "stateChange"
|
||||
// method when the ViewController has...changed its state
|
||||
// register this router with Ionic's NavController
|
||||
// Ionic's NavController will call this NavRouter's "stateChange"
|
||||
// method when the NavController has...changed its state
|
||||
nav.registerRouter(this);
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ export class NavRouter extends RouterOutlet {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
// tell the ViewController which componentType, and it's params, to navigate to
|
||||
// tell the NavController which componentType, and it's params, to navigate to
|
||||
return this.nav.push(componentType, nextInstruction.params);
|
||||
}
|
||||
|
||||
@@ -66,23 +66,23 @@ export class NavRouter extends RouterOutlet {
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} type TODO
|
||||
* @param {TODO} viewItem TODO
|
||||
* @param {TODO} viewCtrl TODO
|
||||
*/
|
||||
stateChange(type, viewItem) {
|
||||
// stateChange is called by Ionic's ViewController
|
||||
stateChange(type, viewCtrl) {
|
||||
// stateChange is called by Ionic's NavController
|
||||
// type could be "push" or "pop"
|
||||
// viewItem is Ionic's ViewItem class, which has the properties "componentType" and "params"
|
||||
// viewCtrl is Ionic's ViewController class, which has the properties "componentType" and "params"
|
||||
|
||||
// only do an update if there's an actual view change
|
||||
if (!viewItem || this._activeViewId === viewItem.id) return;
|
||||
this._activeViewId = viewItem.id;
|
||||
if (!viewCtrl || this._activeViewId === viewCtrl.id) return;
|
||||
this._activeViewId = viewCtrl.id;
|
||||
|
||||
// get the best PathRecognizer for this view's componentType
|
||||
let pathRecognizer = this.getPathRecognizerByComponent(viewItem.componentType);
|
||||
let pathRecognizer = this.getPathRecognizerByComponent(viewCtrl.componentType);
|
||||
if (pathRecognizer) {
|
||||
|
||||
// generate a componentInstruction from the view's PathRecognizer and params
|
||||
let componentInstruction = pathRecognizer.generate(viewItem.params.data);
|
||||
let componentInstruction = pathRecognizer.generate(viewCtrl.params.data);
|
||||
|
||||
// create an Instruction from the componentInstruction
|
||||
let instruction = new Instruction(componentInstruction, null);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {Directive, View, ElementRef, Host, Optional, forwardRef, Injector, NgZone} from 'angular2/angular2';
|
||||
|
||||
import {IonicComponent} from '../../config/decorators';
|
||||
import {ViewController} from '../view/view-controller';
|
||||
import {NavController} from './nav-controller';
|
||||
|
||||
/**
|
||||
* TODO
|
||||
@@ -19,22 +19,22 @@ import {ViewController} from '../view/view-controller';
|
||||
template: '<template pane-anchor></template>',
|
||||
directives: [forwardRef(() => NavPaneAnchor)]
|
||||
})
|
||||
export class Nav extends ViewController {
|
||||
export class Nav extends NavController {
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {ViewController} hostViewCtrl TODO
|
||||
* @param {NavController} hostnavCtrl TODO
|
||||
* @param {Injector} injector TODO
|
||||
* @param {ElementRef} elementRef TODO
|
||||
* @param {NgZone} zone TODO
|
||||
*/
|
||||
constructor(
|
||||
@Optional() hostViewCtrl: ViewController,
|
||||
@Optional() hostnavCtrl: NavController,
|
||||
injector: Injector,
|
||||
elementRef: ElementRef,
|
||||
zone: NgZone
|
||||
) {
|
||||
super(hostViewCtrl, injector, elementRef, zone);
|
||||
super(hostnavCtrl, injector, elementRef, zone);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,7 +2,7 @@ import {Component, Directive, View, ElementRef, Inject, forwardRef, Injector, bi
|
||||
|
||||
import {Ion} from '../ion';
|
||||
import {IonicConfig} from '../../config/config';
|
||||
import {ViewController} from '../view/view-controller';
|
||||
import {NavController} from './nav-controller';
|
||||
import {IonicComponent} from '../../config/decorators';
|
||||
import {PaneAnchor, PaneContentAnchor, NavBarContainer} from './anchors';
|
||||
|
||||
@@ -12,14 +12,14 @@ import {PaneAnchor, PaneContentAnchor, NavBarContainer} from './anchors';
|
||||
export class PaneController {
|
||||
/**
|
||||
* TODO
|
||||
* @param {ViewController} viewCtrl TODO
|
||||
* @param {NavController} navCtrl TODO
|
||||
*/
|
||||
constructor(viewCtrl: ViewController) {
|
||||
constructor(navCtrl: NavController) {
|
||||
this.panes = [];
|
||||
this.viewCtrl = viewCtrl;
|
||||
this.navCtrl = navCtrl;
|
||||
|
||||
this.bindings = Injector.resolve([
|
||||
bind(ViewController).toValue(viewCtrl)
|
||||
bind(NavController).toValue(navCtrl)
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ export class PaneController {
|
||||
// Tabs and view's without a navbar would get a different Panes
|
||||
|
||||
let key = itemStructure.key;
|
||||
let viewCtrl = this.viewCtrl;
|
||||
let navCtrl = this.navCtrl;
|
||||
let pane = this.panes[this.panes.length - 1];
|
||||
|
||||
if (pane && pane.key === key) {
|
||||
@@ -43,7 +43,7 @@ export class PaneController {
|
||||
|
||||
} else {
|
||||
// create a new nav pane
|
||||
viewCtrl.loader.loadNextToLocation(Pane, viewCtrl.anchorElementRef(), this.bindings).then((componentRef) => {
|
||||
navCtrl.loader.loadNextToLocation(Pane, navCtrl.anchorElementRef(), this.bindings).then((componentRef) => {
|
||||
|
||||
// get the pane reference
|
||||
pane = this.newPane;
|
||||
@@ -76,7 +76,7 @@ export class PaneController {
|
||||
// as each section is compiled and added to the Pane
|
||||
// the section will add a reference to itself in the Pane's sections object
|
||||
promises.push(
|
||||
viewCtrl.loader.loadNextToLocation(SectionClass, sectionAnchorElementRef)
|
||||
navCtrl.loader.loadNextToLocation(SectionClass, sectionAnchorElementRef)
|
||||
);
|
||||
});
|
||||
|
||||
@@ -121,14 +121,14 @@ export class PaneController {
|
||||
})
|
||||
export class Pane extends Ion {
|
||||
constructor(
|
||||
@Inject(forwardRef(() => ViewController)) viewCtrl: ViewController,
|
||||
@Inject(forwardRef(() => NavController)) navCtrl: NavController,
|
||||
elementRef: ElementRef,
|
||||
ionicConfig: IonicConfig
|
||||
) {
|
||||
super(elementRef, ionicConfig);
|
||||
viewCtrl.panes.add(this);
|
||||
navCtrl.panes.add(this);
|
||||
this.totalItems = 0;
|
||||
this.zIndex = ++viewCtrl.zIndexes;
|
||||
this.zIndex = ++navCtrl.zIndexes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,27 +3,27 @@ import {SlideEdgeGesture} from 'ionic/gestures/slide-edge-gesture';
|
||||
|
||||
export class SwipeBackGesture extends SlideEdgeGesture {
|
||||
|
||||
constructor(element: Element, opts: Object = {}, viewCtrl) {
|
||||
constructor(element: Element, opts: Object = {}, navCtrl) {
|
||||
super(element, opts);
|
||||
// Can check corners through use of eg 'left top'
|
||||
this.edges = opts.edge.split(' ');
|
||||
this.threshold = opts.threshold;
|
||||
this.viewCtrl = viewCtrl;
|
||||
this.navCtrl = navCtrl;
|
||||
}
|
||||
|
||||
onSlideStart() {
|
||||
this.viewCtrl.swipeBackStart();
|
||||
this.navCtrl.swipeBackStart();
|
||||
}
|
||||
|
||||
onSlide(slide, ev) {
|
||||
this.viewCtrl.swipeBackProgress(slide.distance / slide.max);
|
||||
this.navCtrl.swipeBackProgress(slide.distance / slide.max);
|
||||
}
|
||||
|
||||
onSlideEnd(slide, ev) {
|
||||
let shouldComplete = (Math.abs(ev.velocityX) > 0.2 || Math.abs(slide.delta) > Math.abs(slide.max) * 0.5);
|
||||
|
||||
// TODO: calculate a better playback rate depending on velocity and distance
|
||||
this.viewCtrl.swipeBackEnd(shouldComplete, 1);
|
||||
this.navCtrl.swipeBackEnd(shouldComplete, 1);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,7 +18,7 @@ import {NavParams, NavController} from 'ionic/ionic';
|
||||
'<p>{{title}}</p>' +
|
||||
'<p><button id="from1To2" primary (click)="push()">Push (Go to 2nd)</button></p>' +
|
||||
'<p><button [push-data]="pushData" [nav-push]="pushPage">Push w/ nav-push (Go to 2nd)</button></p>' +
|
||||
'<p><button (click)="setItems()">setItems() (Go to 3rd, no history)</button></p>' +
|
||||
'<p><button (click)="setViews()">setViews() (Go to 3rd, no history)</button></p>' +
|
||||
'<icon class="ion-ios-arrow-back"></icon>' +
|
||||
'<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>' +
|
||||
@@ -39,12 +39,12 @@ class FirstPage {
|
||||
}
|
||||
}
|
||||
|
||||
setItems() {
|
||||
setViews() {
|
||||
let items = [
|
||||
ThirdPage
|
||||
];
|
||||
|
||||
this.nav.setItems(items);
|
||||
this.nav.setViews(items);
|
||||
}
|
||||
|
||||
push() {
|
||||
@@ -61,7 +61,7 @@ class FirstPage {
|
||||
<p><button (click)="pop()">Pop (Go back to 1st)</button></p>
|
||||
<p><button id="from2To1" nav-pop>Pop with NavPop (Go back to 1st)</button></p>
|
||||
<p><button id="from2To3" (click)="push()">Push (Go to 3rd)</button></p>
|
||||
<p><button (click)="setItems()">setItems() (Go to 3rd, FirstPage 1st in history)</button></p>
|
||||
<p><button (click)="setViews()">setViews() (Go to 3rd, FirstPage 1st in history)</button></p>
|
||||
<div class="green"><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></div>
|
||||
</ion-content>
|
||||
`
|
||||
@@ -77,13 +77,13 @@ class SecondPage {
|
||||
console.log('Second page params:', params);
|
||||
}
|
||||
|
||||
setItems() {
|
||||
setViews() {
|
||||
let items = [
|
||||
FirstPage,
|
||||
ThirdPage
|
||||
];
|
||||
|
||||
this.nav.setItems(items);
|
||||
this.nav.setViews(items);
|
||||
}
|
||||
|
||||
pop() {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import {RouteConfig, Location} from 'angular2/router';
|
||||
|
||||
import {App, IonicView, NavParams, ViewItem} from 'ionic/ionic';
|
||||
import {App, IonicView, NavParams, ViewController} from 'ionic/ionic';
|
||||
|
||||
|
||||
@IonicView({templateUrl: 'view1.html'})
|
||||
class View1Cmp {
|
||||
constructor(location: Location, viewItem: ViewItem) {
|
||||
constructor(location: Location, viewCtrl: ViewController) {
|
||||
this.path = location.path();
|
||||
this.viewItem = viewItem;
|
||||
this.viewCtrl = viewCtrl;
|
||||
console.log(`View1Cmp, path: ${this.path}`);
|
||||
}
|
||||
onViewDidEnter() {
|
||||
@@ -18,9 +18,9 @@ class View1Cmp {
|
||||
|
||||
@IonicView({templateUrl: 'view2.html'})
|
||||
class View2Cmp {
|
||||
constructor(location: Location, viewItem: ViewItem) {
|
||||
constructor(location: Location, viewCtrl: ViewController) {
|
||||
this.path = location.path();
|
||||
this.viewItem = viewItem;
|
||||
this.viewCtrl = viewCtrl;
|
||||
console.log(`View2Cmp, path: ${this.path}`);
|
||||
}
|
||||
onViewDidEnter() {
|
||||
@@ -31,10 +31,10 @@ class View2Cmp {
|
||||
|
||||
@IonicView({templateUrl: 'view3.html'})
|
||||
class View3Cmp {
|
||||
constructor(params: NavParams, location: Location, viewItem: ViewItem) {
|
||||
constructor(params: NavParams, location: Location, viewCtrl: ViewController) {
|
||||
this.id = params.get('id');
|
||||
this.path = location.path();
|
||||
this.viewItem = viewItem;
|
||||
this.viewCtrl = viewCtrl;
|
||||
console.log(`View3Cmp, path: ${this.path}, param id: ${this.id}`);
|
||||
}
|
||||
onViewDidEnter() {
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
Location Path: {{path}}
|
||||
</h4>
|
||||
<h4>
|
||||
ViewItem Id: {{viewItem.id}}
|
||||
ViewController Id: {{viewCtrl.id}}
|
||||
</h4>
|
||||
<p>
|
||||
<a href="#/second">Second View via href</a>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
Location Path: {{path}}
|
||||
</h4>
|
||||
<h4>
|
||||
ViewItem Id: {{viewItem.id}}
|
||||
ViewController Id: {{viewCtrl.id}}
|
||||
</h4>
|
||||
<p>
|
||||
<a href="#/third/12">Third View via href, 12 as id param</a>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
NavParams, id: {{id}}
|
||||
</h4>
|
||||
<h4>
|
||||
ViewItem Id: {{viewItem.id}}
|
||||
ViewController Id: {{viewCtrl.id}}
|
||||
</h4>
|
||||
<p>
|
||||
<a href="#/second">Second View via href</a>
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import {Component, EventEmitter, ElementRef, bind, Injector, ComponentRef} from 'angular2/angular2';
|
||||
import {DirectiveBinding} from 'angular2/src/core/compiler/element_injector';
|
||||
|
||||
import {NavParams} from '../nav/nav-controller';
|
||||
import {NavParams} from './nav-controller';
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
export class ViewItem {
|
||||
export class ViewController {
|
||||
|
||||
constructor(viewCtrl, componentType, params = {}) {
|
||||
this.viewCtrl = viewCtrl;
|
||||
constructor(navCtrl, componentType, params = {}) {
|
||||
this.navCtrl = navCtrl;
|
||||
this.componentType = componentType;
|
||||
this.params = new NavParams(params);
|
||||
this.instance = null;
|
||||
@@ -47,9 +47,9 @@ export class ViewItem {
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
stage(callback) {
|
||||
let viewCtrl = this.viewCtrl;
|
||||
let navCtrl = this.navCtrl;
|
||||
|
||||
if (this.instance || !viewCtrl) {
|
||||
if (this.instance || !navCtrl) {
|
||||
// already compiled this view
|
||||
return callback();
|
||||
}
|
||||
@@ -67,19 +67,19 @@ export class ViewItem {
|
||||
ionViewComponentType.token = 'ionView' + this.componentType.name;
|
||||
|
||||
// compile the Component
|
||||
viewCtrl.compiler.compileInHost(ionViewComponentType).then(hostProtoViewRef => {
|
||||
navCtrl.compiler.compileInHost(ionViewComponentType).then(hostProtoViewRef => {
|
||||
|
||||
// figure out the sturcture of this Component
|
||||
// does it have a navbar? Is it tabs? Should it not have a navbar or any toolbars?
|
||||
let itemStructure = this.sturcture = this.inspectStructure(hostProtoViewRef);
|
||||
|
||||
// get the appropriate Pane which this ViewItem will fit into
|
||||
viewCtrl.panes.get(itemStructure, pane => {
|
||||
// get the appropriate Pane which this ViewController will fit into
|
||||
navCtrl.panes.get(itemStructure, pane => {
|
||||
this.pane = pane;
|
||||
|
||||
let bindings = viewCtrl.bindings.concat(Injector.resolve([
|
||||
let bindings = navCtrl.bindings.concat(Injector.resolve([
|
||||
bind(NavParams).toValue(this.params),
|
||||
bind(ViewItem).toValue(this)
|
||||
bind(ViewController).toValue(this)
|
||||
]));
|
||||
|
||||
// add the content of the view to the content area
|
||||
@@ -89,8 +89,8 @@ export class ViewItem {
|
||||
// the same guts as DynamicComponentLoader.loadNextToLocation
|
||||
var hostViewRef =
|
||||
contentContainer.createHostView(hostProtoViewRef, -1, bindings);
|
||||
var newLocation = viewCtrl.viewMngr.getHostElement(hostViewRef);
|
||||
var newComponent = viewCtrl.viewMngr.getComponent(newLocation);
|
||||
var newLocation = navCtrl.viewMngr.getHostElement(hostViewRef);
|
||||
var newComponent = navCtrl.viewMngr.getComponent(newLocation);
|
||||
pane.totalItems++;
|
||||
|
||||
var dispose = () => {
|
||||
@@ -108,12 +108,12 @@ export class ViewItem {
|
||||
this.disposals.push(dispose);
|
||||
var viewComponetRef = new ComponentRef(newLocation, newComponent, dispose);
|
||||
|
||||
// get the component's instance, and set it to the this ViewItem
|
||||
// get the component's instance, and set it to the this ViewController
|
||||
this.setInstance(viewComponetRef.instance);
|
||||
this.viewElementRef(viewComponetRef.location);
|
||||
|
||||
// // get the item container's nav bar
|
||||
let navbarViewContainer = viewCtrl.navbarViewContainer();
|
||||
let navbarViewContainer = navCtrl.navbarViewContainer();
|
||||
|
||||
// // get the item's navbar protoview
|
||||
let navbarTemplateRef = this.templateRefs.navbar;
|
||||
@@ -186,7 +186,7 @@ export class ViewItem {
|
||||
});
|
||||
});
|
||||
|
||||
if (this.viewCtrl.childNavbar()) {
|
||||
if (this.navCtrl.childNavbar()) {
|
||||
navbar = false;
|
||||
}
|
||||
|
||||
@@ -204,8 +204,8 @@ export class ViewItem {
|
||||
*/
|
||||
enableBack() {
|
||||
// update if it's possible to go back from this nav item
|
||||
if (this.viewCtrl) {
|
||||
let previousItem = this.viewCtrl.getPrevious(this);
|
||||
if (this.navCtrl) {
|
||||
let previousItem = this.navCtrl.getPrevious(this);
|
||||
// the previous view may exist, but if it's about to be destroyed
|
||||
// it shouldn't be able to go back to
|
||||
return !!(previousItem && !previousItem.shouldDestroy);
|
||||
@@ -219,11 +219,10 @@ export class ViewItem {
|
||||
*/
|
||||
setInstance(instance) {
|
||||
this.instance = instance;
|
||||
this.instance._viewItem = this;
|
||||
}
|
||||
|
||||
get index() {
|
||||
return (this.viewCtrl ? this.viewCtrl.indexOf(this) : -1);
|
||||
return (this.navCtrl ? this.navCtrl.indexOf(this) : -1);
|
||||
}
|
||||
|
||||
isRoot() {
|
||||
@@ -1,7 +1,7 @@
|
||||
import {Directive, Component, View, Host, ElementRef, forwardRef, Injector, NgZone} from 'angular2/angular2';
|
||||
|
||||
import {ViewController} from '../view/view-controller';
|
||||
import {ViewItem} from '../view/view-item';
|
||||
import {NavController} from '../nav/nav-controller';
|
||||
import {ViewController} from '../nav/view-controller';
|
||||
import {Tabs} from './tabs';
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ import {Tabs} from './tabs';
|
||||
template: '<template pane-anchor></template><ng-content></ng-content>',
|
||||
directives: [forwardRef(() => TabPaneAnchor)]
|
||||
})
|
||||
export class Tab extends ViewController {
|
||||
export class Tab extends NavController {
|
||||
|
||||
/**
|
||||
* TODO
|
||||
@@ -51,32 +51,32 @@ export class Tab extends ViewController {
|
||||
zone: NgZone
|
||||
) {
|
||||
// A Tab is both a container of many views, and is a view itself.
|
||||
// A Tab is one ViewItem within it's Host Tabs (which extends ViewController)
|
||||
// A Tab is a ViewController for its child ViewItems
|
||||
// A Tab is one ViewController within it's Host Tabs (which extends NavController)
|
||||
// A Tab is a NavController for its child ViewControllers
|
||||
super(tabs, injector, elementRef, zone);
|
||||
this.tabs = tabs;
|
||||
|
||||
this.childNavbar(true);
|
||||
|
||||
let item = this.item = new ViewItem(tabs.Host);
|
||||
item.setInstance(this);
|
||||
item.viewElementRef(elementRef);
|
||||
let viewCtrl = this.viewCtrl = new ViewController(tabs.Host);
|
||||
viewCtrl.setInstance(this);
|
||||
viewCtrl.viewElementRef(elementRef);
|
||||
tabs.addTab(this);
|
||||
|
||||
this.navbarView = item.navbarView = () => {
|
||||
let activeItem = this.getActive();
|
||||
return activeItem && activeItem.navbarView();
|
||||
this.navbarView = viewCtrl.navbarView = () => {
|
||||
let activeView = this.getActive();
|
||||
return activeView && activeView.navbarView();
|
||||
};
|
||||
|
||||
item.enableBack = () => {
|
||||
// override ViewItem's enableBack(), should use the
|
||||
viewCtrl.enableBack = () => {
|
||||
// override ViewController's enableBack(), should use the
|
||||
// active child nav item's enableBack() instead
|
||||
let activeItem = this.getActive();
|
||||
return (activeItem && activeItem.enableBack());
|
||||
let activeView = this.getActive();
|
||||
return (activeView && activeView.enableBack());
|
||||
};
|
||||
|
||||
this.panelId = 'tab-panel-' + item.id;
|
||||
this.labeledBy = 'tab-button-' + item.id;
|
||||
this.panelId = 'tab-panel-' + viewCtrl.id;
|
||||
this.labeledBy = 'tab-button-' + viewCtrl.id;
|
||||
}
|
||||
|
||||
onInit() {
|
||||
@@ -118,11 +118,11 @@ export class Tab extends ViewController {
|
||||
}
|
||||
|
||||
get isSelected() {
|
||||
return this.tabs.isActive(this.item);
|
||||
return this.tabs.isActive(this.viewCtrl);
|
||||
}
|
||||
|
||||
get isNotSelected() {
|
||||
return !this.tabs.isActive(this.item);
|
||||
return !this.tabs.isActive(this.viewCtrl);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import {Component, Directive, View, Injector, NgFor, ElementRef, Optional, Host, forwardRef, NgZone} from 'angular2/angular2';
|
||||
|
||||
import {IonicApp} from '../app/app';
|
||||
import {ViewController} from '../view/view-controller';
|
||||
import {ViewItem} from '../view/view-item';
|
||||
import {NavController} from '../nav/nav-controller';
|
||||
import {ViewController} from '../nav/view-controller';
|
||||
import {Icon} from '../icon/icon';
|
||||
import {IonicComponent, IonicView} from '../../config/decorators';
|
||||
|
||||
@@ -50,41 +50,41 @@ import {IonicComponent, IonicView} from '../../config/decorators';
|
||||
'</section>',
|
||||
directives: [forwardRef(() => TabButton)]
|
||||
})
|
||||
export class Tabs extends ViewController {
|
||||
export class Tabs extends NavController {
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
constructor(
|
||||
@Optional() hostViewCtrl: ViewController,
|
||||
@Optional() viewItem: ViewItem,
|
||||
@Optional() hostNavCtrl: NavController,
|
||||
@Optional() viewCtrl: ViewController,
|
||||
app: IonicApp,
|
||||
injector: Injector,
|
||||
elementRef: ElementRef,
|
||||
zone: NgZone
|
||||
) {
|
||||
super(hostViewCtrl, injector, elementRef, zone);
|
||||
super(hostNavCtrl, injector, elementRef, zone);
|
||||
this.app = app;
|
||||
|
||||
// Tabs may also be an actual ViewItem which was navigated to
|
||||
// if Tabs is static and not navigated to within a ViewController
|
||||
// then skip this and don't treat it as it's own ViewItem
|
||||
if (viewItem) {
|
||||
this.item = viewItem;
|
||||
// Tabs may also be an actual ViewController which was navigated to
|
||||
// if Tabs is static and not navigated to within a NavController
|
||||
// then skip this and don't treat it as it's own ViewController
|
||||
if (viewCtrl) {
|
||||
this.viewCtrl = viewCtrl;
|
||||
|
||||
// special overrides for the Tabs ViewItem
|
||||
// the Tabs ViewItem does not have it's own navbar
|
||||
// special overrides for the Tabs ViewController
|
||||
// the Tabs ViewController does not have it's own navbar
|
||||
// so find the navbar it should use within it's active Tab
|
||||
viewItem.navbarView = () => {
|
||||
viewCtrl.navbarView = () => {
|
||||
let activeTab = this.getActive();
|
||||
if (activeTab && activeTab.instance) {
|
||||
return activeTab.instance.navbarView();
|
||||
}
|
||||
};
|
||||
|
||||
// a Tabs ViewItem should not have a back button
|
||||
// a Tabs ViewController should not have a back button
|
||||
// enableBack back button will later be determined
|
||||
// by the active ViewItem that has a navbar
|
||||
viewItem.enableBack = () => {
|
||||
// by the active ViewController that has a navbar
|
||||
ViewController.enableBack = () => {
|
||||
return false;
|
||||
};
|
||||
}
|
||||
@@ -96,14 +96,14 @@ export class Tabs extends ViewController {
|
||||
* @param {Tab} tab TODO
|
||||
*/
|
||||
addTab(tab) {
|
||||
// tab.item refers to the ViewItem of the individual Tab being added to Tabs (ViewController)
|
||||
// this.item refers to the ViewItem instsance on Tabs
|
||||
this.add(tab.item);
|
||||
// tab.viewCtrl refers to the ViewController of the individual Tab being added to Tabs (NavController)
|
||||
// this.viewCtrl refers to the ViewController instsance on Tabs
|
||||
this.add(tab.viewCtrl);
|
||||
|
||||
if (this.length() === 1) {
|
||||
// this was the first tab added, queue this one to be loaded and selected
|
||||
let promise = tab.queueInitial();
|
||||
this.item && this.item.addPromise(promise);
|
||||
this.viewCtrl && this.viewCtrl.addPromise(promise);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,28 +113,28 @@ export class Tabs extends ViewController {
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
select(tab) {
|
||||
let enteringItem = null;
|
||||
let enteringView = null;
|
||||
if (typeof tab === 'number') {
|
||||
enteringItem = this.getByIndex(tab);
|
||||
enteringView = this.getByIndex(tab);
|
||||
} else {
|
||||
enteringItem = this.getByInstance(tab)
|
||||
enteringView = this.getByInstance(tab)
|
||||
}
|
||||
|
||||
if (!enteringItem || !enteringItem.instance || !this.app.isEnabled()) {
|
||||
if (!enteringView || !enteringView.instance || !this.app.isEnabled()) {
|
||||
return Promise.reject();
|
||||
}
|
||||
|
||||
return new Promise(resolve => {
|
||||
enteringItem.instance.load(() => {
|
||||
enteringView.instance.load(() => {
|
||||
let opts = {
|
||||
animate: false
|
||||
};
|
||||
|
||||
let leavingItem = this.getActive() || new ViewItem();
|
||||
leavingItem.shouldDestroy = false;
|
||||
leavingItem.shouldCache = true;
|
||||
let leavingView = this.getActive() || new ViewController();
|
||||
leavingView.shouldDestroy = false;
|
||||
leavingView.shouldCache = true;
|
||||
|
||||
this.transition(enteringItem, leavingItem, opts, () => {
|
||||
this.transition(enteringView, leavingView, opts, () => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
@@ -171,7 +171,7 @@ class TabButton {
|
||||
}
|
||||
|
||||
onInit() {
|
||||
let id = this.tab.item.id;
|
||||
let id = this.tab.viewCtrl.id;
|
||||
this.btnId = 'tab-button-' + id;
|
||||
this.panelId = 'tab-panel-' + id;
|
||||
|
||||
|
||||
@@ -1,780 +0,0 @@
|
||||
import {Compiler, ElementRef, Injector, bind, NgZone} from 'angular2/angular2';
|
||||
import {DynamicComponentLoader} from 'angular2/src/core/compiler/dynamic_component_loader';
|
||||
import {AppViewManager} from 'angular2/src/core/compiler/view_manager';
|
||||
|
||||
import {Ion} from '../ion';
|
||||
import {IonicConfig} from '../../config/config';
|
||||
import {IonicApp} from '../app/app';
|
||||
import {ViewItem} from './view-item';
|
||||
import {NavController} from '../nav/nav-controller';
|
||||
import {PaneController} from '../nav/pane';
|
||||
import {Transition} from '../../transitions/transition';
|
||||
import {SwipeBackGesture} from './swipe-back';
|
||||
import * as util from 'ionic/util';
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
export class ViewController extends Ion {
|
||||
|
||||
constructor(
|
||||
parentViewCtrl: ViewController,
|
||||
injector: Injector,
|
||||
elementRef: ElementRef,
|
||||
zone: NgZone
|
||||
) {
|
||||
let config = injector.get(IonicConfig);
|
||||
super(elementRef, config);
|
||||
|
||||
this.parent = parentViewCtrl;
|
||||
|
||||
this.compiler = injector.get(Compiler);
|
||||
this.loader = injector.get(DynamicComponentLoader);
|
||||
this.viewMngr = injector.get(AppViewManager);
|
||||
this.app = injector.get(IonicApp);
|
||||
this.config = config;
|
||||
this.zone = zone;
|
||||
|
||||
this.items = [];
|
||||
this.panes = new PaneController(this);
|
||||
|
||||
this._sbTrans = null;
|
||||
this.sbEnabled = config.setting('swipeBackEnabled') || false;
|
||||
this.sbThreshold = config.setting('swipeBackThreshold') || 40
|
||||
|
||||
this.id = ++ctrlIds;
|
||||
this._ids = -1;
|
||||
this.zIndexes = -1;
|
||||
|
||||
// build a new injector for child ViewItems to use
|
||||
this.bindings = Injector.resolve([
|
||||
bind(ViewController).toValue(this),
|
||||
bind(NavController).toValue(new NavController(this))
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} componentType TODO
|
||||
* @param {TODO} [params={}] TODO
|
||||
* @param {TODO} [opts={}] TODO
|
||||
* @returns {Promise} TODO
|
||||
*/
|
||||
push(componentType, params = {}, opts = {}) {
|
||||
if (!componentType) {
|
||||
return Promise.reject();
|
||||
}
|
||||
if (typeof componentType !== 'function') {
|
||||
throw 'Loading component must be a component class, not "' + componentType.toString() + '"';
|
||||
}
|
||||
|
||||
let resolve;
|
||||
let promise = new Promise(res => { resolve = res; });
|
||||
|
||||
// do not animate if this is the first in the stack
|
||||
if (!this.items.length) {
|
||||
opts.animation = 'none';
|
||||
}
|
||||
|
||||
// default the direction to "forward"
|
||||
opts.direction = opts.direction || 'forward';
|
||||
|
||||
// the active item is going to be the leaving one (if one exists)
|
||||
let leavingItem = this.getActive() || new ViewItem();
|
||||
leavingItem.shouldCache = (util.isBoolean(opts.cacheLeavingItem) ? opts.cacheLeavingItem : true);
|
||||
leavingItem.shouldDestroy = !leavingItem.shouldCache;
|
||||
if (leavingItem.shouldDestroy) {
|
||||
leavingItem.willUnload();
|
||||
}
|
||||
|
||||
// create a new ViewItem
|
||||
let enteringItem = new ViewItem(this, componentType, params);
|
||||
|
||||
// add the item to the stack
|
||||
this.add(enteringItem);
|
||||
|
||||
if (this.router) {
|
||||
// notify router of the state change
|
||||
this.router.stateChange('push', enteringItem, params);
|
||||
}
|
||||
|
||||
// start the transition
|
||||
this.transition(enteringItem, leavingItem, opts, () => {
|
||||
resolve();
|
||||
});
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} [opts={}] TODO
|
||||
* @returns {Promise} TODO
|
||||
*/
|
||||
pop(opts = {}) {
|
||||
if (!this.canGoBack()) {
|
||||
return Promise.reject();
|
||||
}
|
||||
|
||||
let resolve;
|
||||
let promise = new Promise(res => { resolve = res; });
|
||||
|
||||
// default the direction to "back"
|
||||
opts.direction = opts.direction || 'back';
|
||||
|
||||
// get the active item and set that it is staged to be leaving
|
||||
// was probably the one popped from the stack
|
||||
let leavingItem = this.getActive() || new ViewItem();
|
||||
leavingItem.shouldCache = (util.isBoolean(opts.cacheLeavingItem) ? opts.cacheLeavingItem : false);
|
||||
leavingItem.shouldDestroy = !leavingItem.shouldCache;
|
||||
if (leavingItem.shouldDestroy) {
|
||||
leavingItem.willUnload();
|
||||
}
|
||||
|
||||
// the entering item is now the new last item
|
||||
// Note: we might not have an entering item if this is the
|
||||
// only item on the history stack.
|
||||
let enteringItem = this.getPrevious(leavingItem);
|
||||
if (enteringItem) {
|
||||
if (this.router) {
|
||||
// notify router of the state change
|
||||
this.router.stateChange('pop', enteringItem);
|
||||
}
|
||||
|
||||
// start the transition
|
||||
this.transition(enteringItem, leavingItem, opts, () => {
|
||||
// transition completed, destroy the leaving item
|
||||
resolve();
|
||||
});
|
||||
|
||||
} else {
|
||||
this._transComplete();
|
||||
resolve();
|
||||
}
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the item stack to reflect the given component classes.
|
||||
* @param {TODO} components TODO
|
||||
* @param {TODO} [opts={}] TODO
|
||||
* @returns {Promise} TODO
|
||||
*/
|
||||
setItems(components, opts = {}) {
|
||||
if (!components || !components.length) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
// if animate has not been set then default to false
|
||||
opts.animate = opts.animate || false;
|
||||
|
||||
// ensure leaving items are not cached, and should be destroyed
|
||||
opts.cacheLeavingItem = false;
|
||||
|
||||
// get the items to auto remove without having to do a transiton for each
|
||||
// the last item (the currently active one) will do a normal transition out
|
||||
if (this.items.length > 1) {
|
||||
let autoRemoveItems = this.items.slice(0, this.items.length - 1);
|
||||
for (let i = 0; i < autoRemoveItems.length; i++) {
|
||||
autoRemoveItems[i].shouldDestroy = true;
|
||||
autoRemoveItems[i].shouldCache = false;
|
||||
autoRemoveItems[i].willUnload();
|
||||
}
|
||||
}
|
||||
|
||||
let componentObj = null;
|
||||
let componentType = null;
|
||||
let viewItem = null;
|
||||
|
||||
// create the ViewItems that go before the new active ViewItem in the stack
|
||||
// but the previous views won't should render yet
|
||||
if (components.length > 1) {
|
||||
let newBeforeItems = components.slice(0, components.length - 1);
|
||||
for (let j = 0; j < newBeforeItems.length; j++) {
|
||||
componentObj = newBeforeItems[j];
|
||||
|
||||
if (componentObj) {
|
||||
|
||||
// could be an object with a componentType property, or it is a componentType
|
||||
componentType = componentObj.componentType || componentObj;
|
||||
|
||||
viewItem = new ViewItem(this, componentType, componentObj.params);
|
||||
viewItem.state = CACHED_STATE;
|
||||
viewItem.shouldDestroy = false;
|
||||
viewItem.shouldCache = false;
|
||||
|
||||
// add the item to the stack
|
||||
this.add(viewItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get the component that will become the active item
|
||||
// it'll be the last one in the given components array
|
||||
componentObj = components[ components.length - 1 ];
|
||||
componentType = componentObj.componentType || componentObj;
|
||||
|
||||
// transition the leaving and entering
|
||||
return this.push(componentType, componentObj.params, opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} componentType TODO
|
||||
* @param {TODO} [params={}] TODO
|
||||
* @param {TODO} [opts={}] TODO
|
||||
* @returns {Promise} TODO
|
||||
*/
|
||||
setRoot(componentType, params = {}, opts = {}) {
|
||||
return this.setItems([{
|
||||
componentType,
|
||||
params
|
||||
}], opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} enteringItem TODO
|
||||
* @param {TODO} leavingItem TODO
|
||||
* @param {TODO} opts TODO
|
||||
* @param {Function} callback TODO
|
||||
* @returns {any} TODO
|
||||
*/
|
||||
transition(enteringItem, leavingItem, opts, callback) {
|
||||
if (!enteringItem || enteringItem === leavingItem) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
if (opts.animate === false) {
|
||||
opts.animation = 'none';
|
||||
|
||||
} else if (!opts.animation) {
|
||||
opts.animation = this.config.setting('viewTransition');
|
||||
}
|
||||
|
||||
opts.animate = (opts.animation !== 'none');
|
||||
|
||||
// wait for the new item to complete setup
|
||||
enteringItem.stage(() => {
|
||||
|
||||
this.zone.runOutsideAngular(() => {
|
||||
|
||||
enteringItem.shouldDestroy = false;
|
||||
enteringItem.shouldCache = false;
|
||||
enteringItem.willEnter();
|
||||
leavingItem.willLeave();
|
||||
|
||||
// set that the new item pushed on the stack is staged to be entering/leaving
|
||||
// staged state is important for the transition to find the correct item
|
||||
enteringItem.state = STAGED_ENTERING_STATE;
|
||||
leavingItem.state = STAGED_LEAVING_STATE;
|
||||
|
||||
// init the transition animation
|
||||
let transAnimation = Transition.create(this, opts);
|
||||
if (!opts.animate) {
|
||||
// force it to not animate the elements, just apply the "to" styles
|
||||
transAnimation.duration(0);
|
||||
}
|
||||
|
||||
let duration = transAnimation.duration();
|
||||
if (duration > 64) {
|
||||
// block any clicks during the transition and provide a
|
||||
// fallback to remove the clickblock if something goes wrong
|
||||
this.app.setEnabled(false, duration);
|
||||
}
|
||||
|
||||
// start the transition
|
||||
transAnimation.play().then(() => {
|
||||
|
||||
// transition has completed, update each item's state
|
||||
enteringItem.state = ACTIVE_STATE;
|
||||
leavingItem.state = CACHED_STATE;
|
||||
|
||||
// dispose any items that shouldn't stay around
|
||||
transAnimation.dispose();
|
||||
|
||||
enteringItem.didEnter();
|
||||
leavingItem.didLeave();
|
||||
|
||||
// all done!
|
||||
this.zone.run(() => {
|
||||
this._transComplete();
|
||||
callback();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
swipeBackStart() {
|
||||
if (!this.app.isEnabled() || !this.canSwipeBack()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// disables the app during the transition
|
||||
this.app.setEnabled(false);
|
||||
|
||||
// default the direction to "back"
|
||||
let opts = {
|
||||
direction: 'back'
|
||||
};
|
||||
|
||||
// get the active item and set that it is staged to be leaving
|
||||
// was probably the one popped from the stack
|
||||
let leavingItem = this.getActive() || new ViewItem();
|
||||
leavingItem.shouldDestroy = true;
|
||||
leavingItem.shouldCache = false;
|
||||
leavingItem.willLeave();
|
||||
leavingItem.willUnload();
|
||||
|
||||
// the entering item is now the new last item
|
||||
let enteringItem = this.getPrevious(leavingItem);
|
||||
enteringItem.shouldDestroy = false;
|
||||
enteringItem.shouldCache = false;
|
||||
enteringItem.willEnter();
|
||||
|
||||
// wait for the new item to complete setup
|
||||
enteringItem.stage(() => {
|
||||
|
||||
this.zone.runOutsideAngular(() => {
|
||||
// set that the new item pushed on the stack is staged to be entering/leaving
|
||||
// staged state is important for the transition to find the correct item
|
||||
enteringItem.state = STAGED_ENTERING_STATE;
|
||||
leavingItem.state = STAGED_LEAVING_STATE;
|
||||
|
||||
// init the swipe back transition animation
|
||||
this._sbTrans = Transition.create(this, opts);
|
||||
this._sbTrans.easing('linear').progressStart();
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} progress TODO
|
||||
*/
|
||||
swipeBackProgress(value) {
|
||||
if (this._sbTrans) {
|
||||
// continue to disable the app while actively dragging
|
||||
this.app.setEnabled(false, 4000);
|
||||
|
||||
// set the transition animation's progress
|
||||
this._sbTrans.progress(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {TODO} completeSwipeBack Should the swipe back complete or not.
|
||||
* @param {number} rate How fast it closes
|
||||
*/
|
||||
swipeBackEnd(completeSwipeBack, rate) {
|
||||
if (!this._sbTrans) return;
|
||||
|
||||
// disables the app during the transition
|
||||
this.app.setEnabled(false);
|
||||
|
||||
this._sbTrans.progressEnd(completeSwipeBack, rate).then(() => {
|
||||
|
||||
this.zone.run(() => {
|
||||
// find the items that were entering and leaving
|
||||
let enteringItem = this.getStagedEnteringItem();
|
||||
let leavingItem = this.getStagedLeavingItem();
|
||||
|
||||
if (enteringItem && leavingItem) {
|
||||
// finish up the animation
|
||||
|
||||
if (completeSwipeBack) {
|
||||
// swipe back has completed navigating back
|
||||
// update each item's state
|
||||
enteringItem.state = ACTIVE_STATE;
|
||||
leavingItem.state = CACHED_STATE;
|
||||
|
||||
enteringItem.didEnter();
|
||||
leavingItem.didLeave();
|
||||
|
||||
if (this.router) {
|
||||
// notify router of the pop state change
|
||||
this.router.stateChange('pop', enteringItem);
|
||||
}
|
||||
|
||||
} else {
|
||||
// cancelled the swipe back, they didn't end up going back
|
||||
// return items to their original state
|
||||
leavingItem.state = ACTIVE_STATE;
|
||||
enteringItem.state = CACHED_STATE;
|
||||
|
||||
leavingItem.willEnter();
|
||||
leavingItem.didEnter();
|
||||
enteringItem.didLeave();
|
||||
|
||||
leavingItem.shouldDestroy = false;
|
||||
enteringItem.shouldDestroy = false;
|
||||
}
|
||||
}
|
||||
|
||||
// empty out and dispose the swipe back transition animation
|
||||
this._sbTrans && this._sbTrans.dispose();
|
||||
this._sbTrans = null;
|
||||
|
||||
// all done!
|
||||
this._transComplete();
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
_runSwipeBack() {
|
||||
if (this.canSwipeBack()) {
|
||||
// it is possible to swipe back
|
||||
|
||||
if (this.sbGesture) {
|
||||
// this is already an active gesture, don't create another one
|
||||
return;
|
||||
}
|
||||
|
||||
let opts = {
|
||||
edge: 'left',
|
||||
threshold: this.sbThreshold
|
||||
};
|
||||
this.sbGesture = new SwipeBackGesture(this.getNativeElement(), opts, this);
|
||||
console.debug('SwipeBackGesture listen');
|
||||
this.sbGesture.listen();
|
||||
|
||||
|
||||
} else if (this.sbGesture) {
|
||||
// it is not possible to swipe back and there is an
|
||||
// active sbGesture, so unlisten it
|
||||
console.debug('SwipeBackGesture unlisten');
|
||||
this.sbGesture.unlisten();
|
||||
this.sbGesture = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} val TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
isSwipeBackEnabled(val) {
|
||||
if (arguments.length) {
|
||||
this.sbEnabled = !!val;
|
||||
}
|
||||
return this.sbEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* If it's possible to use swipe back or not. If it's not possible
|
||||
* to go back, or swipe back is not enable then this will return false.
|
||||
* If it is possible to go back, and swipe back is enabled, then this
|
||||
* will return true.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
canSwipeBack() {
|
||||
return (this.sbEnabled && this.canGoBack());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns `true` if there's a valid previous view that we can pop back to.
|
||||
* Otherwise returns false.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
canGoBack() {
|
||||
let activeItem = this.getActive();
|
||||
if (activeItem) {
|
||||
return activeItem.enableBack();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_transComplete() {
|
||||
let destroys = [];
|
||||
|
||||
this.items.forEach(item => {
|
||||
if (item) {
|
||||
if (item.shouldDestroy) {
|
||||
destroys.push(item);
|
||||
|
||||
} else if (item.state === CACHED_STATE && item.shouldCache) {
|
||||
item.shouldCache = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
destroys.forEach(item => {
|
||||
this.remove(item);
|
||||
item.destroy();
|
||||
});
|
||||
|
||||
// allow clicks again, but still set an enable time
|
||||
// meaning nothing with this view controller can happen for XXms
|
||||
this.app.setEnabled(true);
|
||||
|
||||
if (this.items.length === 1) {
|
||||
this.elementRef.nativeElement.classList.add('has-views');
|
||||
}
|
||||
|
||||
this._runSwipeBack();
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
getActive() {
|
||||
for (let i = 0, ii = this.items.length; i < ii; i++) {
|
||||
if (this.items[i].state === ACTIVE_STATE) {
|
||||
return this.items[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} instance TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
getByInstance(instance) {
|
||||
if (instance) {
|
||||
for (let i = 0, ii = this.items.length; i < ii; i++) {
|
||||
if (this.items[i].instance === instance) {
|
||||
return this.items[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} index TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
getByIndex(index) {
|
||||
if (index < this.items.length && index > -1) {
|
||||
return this.items[index];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} item TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
getPrevious(item) {
|
||||
if (item) {
|
||||
return this.items[ this.items.indexOf(item) - 1 ];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
getStagedEnteringItem() {
|
||||
for (let i = 0, ii = this.items.length; i < ii; i++) {
|
||||
if (this.items[i].state === STAGED_ENTERING_STATE) {
|
||||
return this.items[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
getStagedLeavingItem() {
|
||||
for (let i = 0, ii = this.items.length; i < ii; i++) {
|
||||
if (this.items[i].state === STAGED_LEAVING_STATE) {
|
||||
return this.items[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} nbContainer TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
navbarViewContainer(nbContainer) {
|
||||
if (nbContainer) {
|
||||
this._nbContainer = nbContainer;
|
||||
}
|
||||
if (this._nbContainer) {
|
||||
return this._nbContainer;
|
||||
}
|
||||
if (this.parent) {
|
||||
return this.parent.navbarViewContainer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
anchorElementRef() {
|
||||
if (arguments.length) {
|
||||
this._anchorER = arguments[0];
|
||||
}
|
||||
return this._anchorER;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
anchorViewContainerRef() {
|
||||
if (arguments.length) {
|
||||
this._anchorVC = arguments[0];
|
||||
}
|
||||
return this._anchorVC;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
childNavbar() {
|
||||
if (arguments.length) {
|
||||
this._childNavbar = arguments[0];
|
||||
}
|
||||
return this._childNavbar;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} item TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
add(item) {
|
||||
item.id = this.id + '-' + (++this._ids);
|
||||
this.items.push(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} itemOrIndex TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
remove(itemOrIndex) {
|
||||
util.array.remove(this.items, itemOrIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* First view item in this view controller's stack. This would
|
||||
* not return an item which is about to be destroyed.
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
first() {
|
||||
for (let i = 0, l = this.items.length; i < l; i++) {
|
||||
if (!this.items[i].shouldDestroy) {
|
||||
return this.items[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Last view item in this view controller's stack. This would
|
||||
* not return an item which is about to be destroyed.
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
last() {
|
||||
for (let i = this.items.length - 1; i >= 0; i--) {
|
||||
if (!this.items[i].shouldDestroy) {
|
||||
return this.items[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} item TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
indexOf(item) {
|
||||
return this.items.indexOf(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of sibling view items in the view controller. This does
|
||||
* not include items which are about to be destroyed.
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
length() {
|
||||
let len = 0;
|
||||
for (let i = 0, l = this.items.length; i < l; i++) {
|
||||
if (!this.items[i].shouldDestroy) {
|
||||
len++;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
instances() {
|
||||
let instances = [];
|
||||
for (let item of this.items) {
|
||||
if (item.instance) {
|
||||
instances.push(item.instance);
|
||||
}
|
||||
}
|
||||
return instances;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} item TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
isActive(item) {
|
||||
return (item && item.state === ACTIVE_STATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} item TODO
|
||||
* @returns {TODO} TODO
|
||||
*/
|
||||
isStagedEntering(item) {
|
||||
return (item && item.state === STAGED_ENTERING_STATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
* @param {TODO} router TODO
|
||||
*/
|
||||
registerRouter(router) {
|
||||
this.router = router;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const ACTIVE_STATE = 1;
|
||||
const CACHED_STATE = 2;
|
||||
const STAGED_ENTERING_STATE = 3;
|
||||
const STAGED_LEAVING_STATE = 4;
|
||||
|
||||
let ctrlIds = -1;
|
||||
@@ -1,17 +0,0 @@
|
||||
|
||||
// View
|
||||
// --------------------------------------------------
|
||||
|
||||
ion-view {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex-direction: column;
|
||||
|
||||
background-color: white;
|
||||
|
||||
transform: translateZ(0px);
|
||||
}
|
||||
@@ -47,8 +47,7 @@
|
||||
"components/search-bar/search-bar",
|
||||
"components/segment/segment",
|
||||
"components/switch/switch",
|
||||
"components/tabs/tabs",
|
||||
"components/view/view";
|
||||
"components/tabs/tabs";
|
||||
|
||||
|
||||
// Ionicons
|
||||
|
||||
@@ -14,61 +14,61 @@ export class Transition extends Animation {
|
||||
super();
|
||||
|
||||
// get the entering and leaving items
|
||||
let enteringItem = this.entering = nav.getStagedEnteringItem();
|
||||
let leavingItem = this.leaving = nav.getStagedLeavingItem();
|
||||
let enteringView = this.entering = nav.getStagedenteringView();
|
||||
let leavingView = this.leaving = nav.getStagedleavingView();
|
||||
|
||||
// create animation for the entering item's "ion-view" element
|
||||
this.enteringView = new Animation(enteringItem.viewElementRef());
|
||||
this.enteringView = new Animation(enteringView.viewElementRef());
|
||||
this.enteringView.before.addClass(SHOW_VIEW_CSS);
|
||||
|
||||
this.enteringView.onPlay(() => {
|
||||
enteringItem.postRender();
|
||||
enteringView.postRender();
|
||||
});
|
||||
|
||||
this.add(this.enteringView);
|
||||
|
||||
if (opts.navbar !== false) {
|
||||
|
||||
let enteringNavbar = this.enteringNavbar = new Animation(enteringItem.navbarRef());
|
||||
let enteringNavbar = this.enteringNavbar = new Animation(enteringView.navbarRef());
|
||||
enteringNavbar.before.addClass(SHOW_NAVBAR_CSS);
|
||||
|
||||
if (enteringItem.enableBack()) {
|
||||
if (enteringView.enableBack()) {
|
||||
// only animate in the back button if the entering view has it enabled
|
||||
let enteringBackButton = this.enteringBackButton = new Animation(enteringItem.backBtnRef());
|
||||
let enteringBackButton = this.enteringBackButton = new Animation(enteringView.backBtnRef());
|
||||
enteringBackButton
|
||||
.before.addClass(SHOW_BACK_BUTTON)
|
||||
.fadeIn();
|
||||
enteringNavbar.add(enteringBackButton);
|
||||
}
|
||||
|
||||
this.enteringTitle = new Animation(enteringItem.titleRef());
|
||||
this.enteringTitle = new Animation(enteringView.titleRef());
|
||||
enteringNavbar.add(this.enteringTitle);
|
||||
this.add(enteringNavbar);
|
||||
|
||||
this.enteringNavbarItems = new Animation(enteringItem.navbarItemRefs());
|
||||
this.enteringNavbarItems = new Animation(enteringView.navbarItemRefs());
|
||||
this.enteringNavbarItems.fadeIn();
|
||||
enteringNavbar.add(this.enteringNavbarItems);
|
||||
}
|
||||
|
||||
|
||||
if (leavingItem) {
|
||||
if (leavingView) {
|
||||
// setup the leaving item if one exists (initial viewing wouldn't have a leaving item)
|
||||
this.leavingView = new Animation(leavingItem.viewElementRef());
|
||||
this.leavingView = new Animation(leavingView.viewElementRef());
|
||||
this.leavingView.after.removeClass(SHOW_VIEW_CSS);
|
||||
|
||||
let leavingNavbar = this.leavingNavbar = new Animation(leavingItem.navbarRef());
|
||||
let leavingNavbar = this.leavingNavbar = new Animation(leavingView.navbarRef());
|
||||
leavingNavbar.after.removeClass(SHOW_NAVBAR_CSS);
|
||||
|
||||
let leavingBackButton = this.leavingBackButton = new Animation(leavingItem.backBtnRef());
|
||||
let leavingBackButton = this.leavingBackButton = new Animation(leavingView.backBtnRef());
|
||||
leavingBackButton
|
||||
.after.removeClass(SHOW_BACK_BUTTON)
|
||||
.fadeOut();
|
||||
leavingNavbar.add(leavingBackButton);
|
||||
|
||||
this.leavingTitle = new Animation(leavingItem.titleRef());
|
||||
this.leavingTitle = new Animation(leavingView.titleRef());
|
||||
leavingNavbar.add(this.leavingTitle);
|
||||
|
||||
this.leavingNavbarItems = new Animation(leavingItem.navbarItemRefs());
|
||||
this.leavingNavbarItems = new Animation(leavingView.navbarItemRefs());
|
||||
this.leavingNavbarItems.fadeOut();
|
||||
leavingNavbar.add(this.leavingNavbarItems);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user