mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
refactor(nav): usign enums
This commit is contained in:
@@ -2,14 +2,6 @@ import { ViewController, isViewController } from './view-controller';
|
||||
import { NavControllerBase } from './nav';
|
||||
import { Transition } from './transition';
|
||||
|
||||
|
||||
export type NavParams = {[key: string]: any};
|
||||
|
||||
export interface PageMeta {
|
||||
page: string | HTMLElement | ViewController;
|
||||
params?: any;
|
||||
}
|
||||
|
||||
export function convertToView(page: any, params: any): ViewController {
|
||||
if (!page) {
|
||||
return null;
|
||||
@@ -21,27 +13,25 @@ export function convertToView(page: any, params: any): ViewController {
|
||||
}
|
||||
|
||||
export function convertToViews(pages: any[]): ViewController[] {
|
||||
return pages
|
||||
.map(page => {
|
||||
if (isViewController(page)) {
|
||||
return page;
|
||||
}
|
||||
if ('page' in page) {
|
||||
return convertToView(page.page, page.params);
|
||||
}
|
||||
return convertToView(page, undefined);
|
||||
})
|
||||
.filter(v => v !== null);
|
||||
return pages.map(page => {
|
||||
if (isViewController(page)) {
|
||||
return page;
|
||||
}
|
||||
if ('page' in page) {
|
||||
return convertToView(page.page, page.params);
|
||||
}
|
||||
return convertToView(page, undefined);
|
||||
})
|
||||
.filter(v => v !== null);
|
||||
}
|
||||
|
||||
|
||||
export function setZIndex(nav: NavControllerBase, enteringView: ViewController, leavingView: ViewController, direction: string) {
|
||||
if (enteringView) {
|
||||
|
||||
leavingView = leavingView || nav.getPrevious(enteringView);
|
||||
|
||||
if (leavingView && isPresent(leavingView._zIndex)) {
|
||||
if (direction === DIRECTION_BACK) {
|
||||
if (direction === NavDirection.back) {
|
||||
enteringView._setZIndex(leavingView._zIndex - 1);
|
||||
|
||||
} else {
|
||||
@@ -54,43 +44,25 @@ export function setZIndex(nav: NavControllerBase, enteringView: ViewController,
|
||||
}
|
||||
}
|
||||
|
||||
export function isTabs(nav: any): boolean {
|
||||
// Tabs (ion-tabs)
|
||||
return !!nav && !!nav.getSelected;
|
||||
export function isPresent(val: any): val is any {
|
||||
return val !== undefined && val !== null;
|
||||
}
|
||||
|
||||
export function isTab(nav: any): boolean {
|
||||
// Tab (ion-tab)
|
||||
return !!nav && isPresent(nav._tabId);
|
||||
export const enum ViewState {
|
||||
New = 1,
|
||||
Initialized,
|
||||
Attached,
|
||||
Destroyed
|
||||
}
|
||||
|
||||
export function isNav(nav: any): boolean {
|
||||
// Nav (ion-nav), Tab (ion-tab), Portal (ion-portal)
|
||||
return !!nav && !!nav.push && nav.getType() === 'nav';
|
||||
export const enum NavDirection {
|
||||
back = 'back',
|
||||
forward = 'forward'
|
||||
}
|
||||
|
||||
export function linkToSegment(navId: string, type: string, secondaryId: string, link: NavLink): NavSegment {
|
||||
const segment = <NavSegment> Object.assign({}, link);
|
||||
segment.navId = navId;
|
||||
segment.type = type;
|
||||
segment.secondaryId = secondaryId;
|
||||
return segment;
|
||||
}
|
||||
export const INIT_ZINDEX = 100;
|
||||
|
||||
|
||||
// internal link interface, not exposed publicly
|
||||
export interface NavLink {
|
||||
component?: any;
|
||||
loadChildren?: string;
|
||||
name?: string;
|
||||
segment?: string;
|
||||
segmentParts?: string[];
|
||||
segmentPartsLen?: number;
|
||||
staticLen?: number;
|
||||
dataLen?: number;
|
||||
dataKeys?: {[key: string]: boolean};
|
||||
defaultHistory?: any[];
|
||||
}
|
||||
export type NavParams = {[key: string]: any};
|
||||
|
||||
export interface NavResult {
|
||||
hasCompleted: boolean;
|
||||
@@ -100,36 +72,6 @@ export interface NavResult {
|
||||
direction?: string;
|
||||
}
|
||||
|
||||
export interface NavSegment extends DehydratedSegment {
|
||||
type: string;
|
||||
navId: string;
|
||||
secondaryId: string;
|
||||
requiresExplicitNavPrefix?: boolean;
|
||||
}
|
||||
|
||||
export interface DehydratedSegment {
|
||||
id: string;
|
||||
name: string;
|
||||
component?: any;
|
||||
loadChildren?: string;
|
||||
data: any;
|
||||
defaultHistory?: NavSegment[];
|
||||
secondaryId?: string;
|
||||
}
|
||||
|
||||
export interface DehydratedSegmentPair {
|
||||
segments: DehydratedSegment[];
|
||||
navGroup: NavGroup;
|
||||
}
|
||||
|
||||
export interface NavGroup {
|
||||
type: string;
|
||||
navId: string;
|
||||
secondaryId: string;
|
||||
segmentPieces?: string[];
|
||||
tabSegmentPieces?: string[];
|
||||
}
|
||||
|
||||
export interface NavOptions {
|
||||
animate?: boolean;
|
||||
animation?: string;
|
||||
@@ -147,8 +89,6 @@ export interface NavOptions {
|
||||
viewIsReady?: () => Promise<any>;
|
||||
}
|
||||
|
||||
export function isPresent(val: any): val is any { return val !== undefined && val !== null; }
|
||||
|
||||
export interface Page extends Function {
|
||||
new (...args: any[]): any;
|
||||
}
|
||||
@@ -179,17 +119,3 @@ export interface TransitionInstruction {
|
||||
enteringRequiresTransition?: boolean;
|
||||
requiresTransition?: boolean;
|
||||
}
|
||||
|
||||
export const STATE_NEW = 1;
|
||||
export const STATE_INITIALIZED = 2;
|
||||
export const STATE_ATTACHED = 3;
|
||||
export const STATE_DESTROYED = 4;
|
||||
|
||||
export const INIT_ZINDEX = 100;
|
||||
|
||||
export const DIRECTION_BACK = 'back';
|
||||
export const DIRECTION_FORWARD = 'forward';
|
||||
export const DIRECTION_SWITCH = 'switch';
|
||||
|
||||
export const NAV = 'nav';
|
||||
export const TABS = 'tabs';
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
import { Build, Component, Element, Event, EventEmitter, Method, Prop, Watch } from '@stencil/core';
|
||||
import {
|
||||
DIRECTION_BACK,
|
||||
DIRECTION_FORWARD,
|
||||
INIT_ZINDEX,
|
||||
NavDirection,
|
||||
NavOptions,
|
||||
NavParams,
|
||||
NavResult,
|
||||
STATE_ATTACHED,
|
||||
STATE_DESTROYED,
|
||||
STATE_INITIALIZED,
|
||||
STATE_NEW,
|
||||
TransitionDoneFn,
|
||||
TransitionInstruction,
|
||||
ViewState,
|
||||
convertToViews,
|
||||
isPresent,
|
||||
setZIndex
|
||||
@@ -19,6 +15,7 @@ import {
|
||||
|
||||
import { ViewController, isViewController } from './view-controller';
|
||||
import { AnimationOptions, Config, DomController, GestureDetail, NavOutlet } from '../..';
|
||||
import { RouteID, RouteWrite } from '../router/utils/interfaces';
|
||||
import { assert } from '../../utils/helpers';
|
||||
|
||||
import { TransitionController } from './transition-controller';
|
||||
@@ -26,7 +23,6 @@ import { Transition } from './transition';
|
||||
|
||||
import iosTransitionAnimation from './animations/ios.transition';
|
||||
import mdTransitionAnimation from './animations/md.transition';
|
||||
import { RouteID, RouteWrite } from '../router/utils/interfaces';
|
||||
|
||||
const TrnsCtrl = new TransitionController();
|
||||
|
||||
@@ -208,6 +204,7 @@ export class NavControllerBase implements NavOutlet {
|
||||
if (active && active.component === id) {
|
||||
return Promise.resolve({changed: false});
|
||||
}
|
||||
const viewController = this._views.find(v => v.component === id) || id;
|
||||
|
||||
let resolve: (result: RouteWrite) => void;
|
||||
const promise = new Promise<RouteWrite>((r) => resolve = r);
|
||||
@@ -215,7 +212,7 @@ export class NavControllerBase implements NavOutlet {
|
||||
const commonOpts: NavOptions = {
|
||||
viewIsReady: () => {
|
||||
let markVisible;
|
||||
const p = new Promise((r) => markVisible = r);
|
||||
const p = new Promise(r => markVisible = r);
|
||||
resolve({
|
||||
changed: true,
|
||||
markVisible
|
||||
@@ -225,17 +222,15 @@ export class NavControllerBase implements NavOutlet {
|
||||
};
|
||||
|
||||
if (direction === 1) {
|
||||
this.push(id, params, commonOpts);
|
||||
this.push(viewController, params, commonOpts);
|
||||
} else if (direction === -1) {
|
||||
this.canGoBack()
|
||||
? this.pop(commonOpts)
|
||||
: this.setRoot(id, params, {
|
||||
...commonOpts,
|
||||
direction: DIRECTION_BACK,
|
||||
animate: true
|
||||
});
|
||||
this.setRoot(id, params, {
|
||||
...commonOpts,
|
||||
direction: NavDirection.back,
|
||||
animate: true
|
||||
});
|
||||
} else {
|
||||
this.setRoot(id, params, commonOpts);
|
||||
this.setRoot(viewController, params, commonOpts);
|
||||
}
|
||||
return promise;
|
||||
}
|
||||
@@ -365,7 +360,7 @@ export class NavControllerBase implements NavOutlet {
|
||||
// let's see if there's another to kick off
|
||||
this._nextTrns();
|
||||
const router = document.querySelector('ion-router');
|
||||
const isPop = result.direction === DIRECTION_BACK;
|
||||
const isPop = result.direction === NavDirection.back;
|
||||
if (router) {
|
||||
router.navChanged(isPop);
|
||||
}
|
||||
@@ -441,7 +436,7 @@ export class NavControllerBase implements NavOutlet {
|
||||
// Needs transition?
|
||||
ti.requiresTransition = (ti.enteringRequiresTransition || ti.leavingRequiresTransition) && enteringView !== leavingView;
|
||||
|
||||
if (enteringView && enteringView._state === STATE_NEW) {
|
||||
if (enteringView && enteringView._state === ViewState.New) {
|
||||
this._viewInit(enteringView);
|
||||
}
|
||||
})
|
||||
@@ -522,7 +517,7 @@ export class NavControllerBase implements NavOutlet {
|
||||
if (nav && nav !== this) {
|
||||
throw new Error('inserted view was already inserted');
|
||||
}
|
||||
if (view._state === STATE_DESTROYED) {
|
||||
if (view._state === ViewState.Destroyed) {
|
||||
throw new Error('inserted view was already destroyed');
|
||||
}
|
||||
}
|
||||
@@ -575,7 +570,7 @@ export class NavControllerBase implements NavOutlet {
|
||||
}
|
||||
}
|
||||
// default the direction to "back"
|
||||
opts.direction = opts.direction || DIRECTION_BACK;
|
||||
opts.direction = opts.direction || NavDirection.back;
|
||||
}
|
||||
|
||||
const finalBalance = this._views.length + (insertViews ? insertViews.length : 0) - (removeCount ? removeCount : 0);
|
||||
@@ -603,7 +598,7 @@ export class NavControllerBase implements NavOutlet {
|
||||
|
||||
if (ti.enteringRequiresTransition) {
|
||||
// default to forward if not already set
|
||||
opts.direction = opts.direction || DIRECTION_FORWARD;
|
||||
opts.direction = opts.direction || NavDirection.forward;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -640,15 +635,14 @@ export class NavControllerBase implements NavOutlet {
|
||||
*/
|
||||
private _viewInit(enteringView: ViewController) {
|
||||
assert(enteringView, 'enteringView must be non null');
|
||||
assert(enteringView._state === STATE_NEW, 'enteringView state must be NEW');
|
||||
assert(enteringView._state === ViewState.New, 'enteringView state must be NEW');
|
||||
|
||||
enteringView._state = STATE_INITIALIZED;
|
||||
enteringView._state = ViewState.Initialized;
|
||||
enteringView.init();
|
||||
enteringView._preLoad();
|
||||
}
|
||||
|
||||
private _viewAttachToDOM(view: ViewController) {
|
||||
assert(view._state === STATE_INITIALIZED, 'view state must be INITIALIZED');
|
||||
assert(view._state === ViewState.Initialized, 'view state must be INITIALIZED');
|
||||
|
||||
// fire willLoad before change detection runs
|
||||
view._willLoad();
|
||||
@@ -657,7 +651,7 @@ export class NavControllerBase implements NavOutlet {
|
||||
// ******** DOM WRITE ****************
|
||||
this.el.appendChild(view.element);
|
||||
|
||||
view._state = STATE_ATTACHED;
|
||||
view._state = ViewState.Attached;
|
||||
|
||||
// successfully finished loading the entering view
|
||||
// fire off the "didLoad" lifecycle events
|
||||
@@ -726,7 +720,7 @@ export class NavControllerBase implements NavOutlet {
|
||||
.then(() => this._transitionInit(transition, enteringView, leavingView, opts))
|
||||
.then(() => this._transitionStart(transition, enteringView, leavingView, opts));
|
||||
|
||||
if (enteringView && (enteringView._state === STATE_INITIALIZED)) {
|
||||
if (enteringView && (enteringView._state === ViewState.Initialized)) {
|
||||
// render the entering component in the DOM
|
||||
// this would also render new child navs/views
|
||||
// which may have their very own async canEnter/Leave tests
|
||||
@@ -894,7 +888,7 @@ export class NavControllerBase implements NavOutlet {
|
||||
}
|
||||
|
||||
private _removeView(view: ViewController) {
|
||||
assert(view._state === STATE_ATTACHED || view._state === STATE_DESTROYED, 'view state should be loaded or destroyed');
|
||||
assert(view._state === ViewState.Attached || view._state === ViewState.Destroyed, 'view state should be loaded or destroyed');
|
||||
|
||||
const views = this._views;
|
||||
const index = views.indexOf(view);
|
||||
@@ -988,7 +982,7 @@ export class NavControllerBase implements NavOutlet {
|
||||
|
||||
// default the direction to "back";
|
||||
const opts: NavOptions = {
|
||||
direction: DIRECTION_BACK,
|
||||
direction: NavDirection.back,
|
||||
progressAnimation: true
|
||||
};
|
||||
|
||||
|
||||
@@ -2,13 +2,10 @@ import { isPresent } from './nav-util';
|
||||
import { Transition } from './transition';
|
||||
import { NavControllerBase } from './nav';
|
||||
|
||||
|
||||
export class TransitionController {
|
||||
private _ids = 0;
|
||||
private _trns = new Map<number, Transition>();
|
||||
|
||||
// constructor(public plt: Platform, private _config: Config) {}
|
||||
|
||||
getRootTrnsId(nav: NavControllerBase): number {
|
||||
nav = nav.parent;
|
||||
while (nav) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
import { NavOptions, STATE_ATTACHED, STATE_DESTROYED, STATE_INITIALIZED, STATE_NEW } from './nav-util';
|
||||
import { NavOptions, ViewState } from './nav-util';
|
||||
import { NavControllerBase } from './nav';
|
||||
import { assert } from '../../utils/helpers';
|
||||
|
||||
@@ -29,7 +29,7 @@ export class ViewController {
|
||||
|
||||
_nav: NavControllerBase;
|
||||
_zIndex: number;
|
||||
_state: number = STATE_NEW;
|
||||
_state: ViewState = ViewState.New;
|
||||
|
||||
/** @hidden */
|
||||
id: string;
|
||||
@@ -162,10 +162,6 @@ export class ViewController {
|
||||
}
|
||||
}
|
||||
|
||||
_preLoad() {
|
||||
assert(this._state === STATE_INITIALIZED, 'view state must be INITIALIZED');
|
||||
this._lifecycle('PreLoad');
|
||||
}
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
@@ -173,7 +169,7 @@ export class ViewController {
|
||||
* This event is fired before the component and his children have been initialized.
|
||||
*/
|
||||
_willLoad() {
|
||||
assert(this._state === STATE_INITIALIZED, 'view state must be INITIALIZED');
|
||||
assert(this._state === ViewState.Initialized, 'view state must be INITIALIZED');
|
||||
this._lifecycle('WillLoad');
|
||||
}
|
||||
|
||||
@@ -186,7 +182,7 @@ export class ViewController {
|
||||
* recommended method to use when a view becomes active.
|
||||
*/
|
||||
_didLoad() {
|
||||
assert(this._state === STATE_ATTACHED, 'view state must be ATTACHED');
|
||||
assert(this._state === ViewState.Attached, 'view state must be ATTACHED');
|
||||
this._lifecycle('DidLoad');
|
||||
}
|
||||
|
||||
@@ -195,7 +191,7 @@ export class ViewController {
|
||||
* The view is about to enter and become the active view.
|
||||
*/
|
||||
_willEnter() {
|
||||
assert(this._state === STATE_ATTACHED, 'view state must be ATTACHED');
|
||||
assert(this._state === ViewState.Attached, 'view state must be ATTACHED');
|
||||
|
||||
if (this._detached) {
|
||||
// ensure this has been re-attached to the change detector
|
||||
@@ -214,10 +210,8 @@ export class ViewController {
|
||||
* will fire, whether it was the first load or loaded from the cache.
|
||||
*/
|
||||
_didEnter() {
|
||||
assert(this._state === STATE_ATTACHED, 'view state must be ATTACHED');
|
||||
assert(this._state === ViewState.Attached, 'view state must be ATTACHED');
|
||||
|
||||
// this._nb && this._nb.didEnter();
|
||||
// this.didEnter.emit(null);
|
||||
this._lifecycle('DidEnter');
|
||||
}
|
||||
|
||||
@@ -226,7 +220,6 @@ export class ViewController {
|
||||
* The view is about to leave and no longer be the active view.
|
||||
*/
|
||||
_willLeave(_willUnload: boolean) {
|
||||
// this.willLeave.emit(null);
|
||||
this._lifecycle('WillLeave');
|
||||
}
|
||||
|
||||
@@ -236,7 +229,6 @@ export class ViewController {
|
||||
* will fire, whether it is cached or unloaded.
|
||||
*/
|
||||
_didLeave() {
|
||||
// this.didLeave.emit(null);
|
||||
this._lifecycle('DidLeave');
|
||||
|
||||
// when this is not the active page
|
||||
@@ -252,7 +244,6 @@ export class ViewController {
|
||||
* @hidden
|
||||
*/
|
||||
_willUnload() {
|
||||
// this.willUnload.emit(null);
|
||||
this._lifecycle('WillUnload');
|
||||
}
|
||||
|
||||
@@ -261,18 +252,15 @@ export class ViewController {
|
||||
* DOM WRITE
|
||||
*/
|
||||
_destroy() {
|
||||
assert(this._state !== STATE_DESTROYED, 'view state must be ATTACHED');
|
||||
assert(this._state !== ViewState.Destroyed, 'view state must be ATTACHED');
|
||||
|
||||
const element = this.element;
|
||||
if (element) {
|
||||
// completely destroy this component. boom.
|
||||
// TODO
|
||||
// this._cmp.destroy();
|
||||
element.remove();
|
||||
}
|
||||
|
||||
this._nav = this._cntDir = this._leavingOpts = null;
|
||||
this._state = STATE_DESTROYED;
|
||||
this._state = ViewState.Destroyed;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -313,7 +301,6 @@ export class ViewController {
|
||||
});
|
||||
this.element.dispatchEvent(event);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export function isViewController(viewCtrl: any): viewCtrl is ViewController {
|
||||
|
||||
Reference in New Issue
Block a user