mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-18 03:00:58 +08:00
refactor(router): remove getContainerEl()
This commit is contained in:
@ -11,7 +11,7 @@ const OFF_OPACITY = 0.8;
|
|||||||
|
|
||||||
export default function iosTransitionAnimation(Animation: Animation, navEl: HTMLElement, opts: AnimationOptions): Promise<Animation> {
|
export default function iosTransitionAnimation(Animation: Animation, navEl: HTMLElement, opts: AnimationOptions): Promise<Animation> {
|
||||||
|
|
||||||
const isRTL = opts.isRTL;
|
const isRTL = document.dir === 'rtl';
|
||||||
const OFF_RIGHT = isRTL ? '-99.5%' : '99.5%';
|
const OFF_RIGHT = isRTL ? '-99.5%' : '99.5%';
|
||||||
const OFF_LEFT = isRTL ? '31%' : '-31%';
|
const OFF_LEFT = isRTL ? '31%' : '-31%';
|
||||||
|
|
||||||
|
@ -14,11 +14,11 @@ import {
|
|||||||
import { ViewController, isViewController } from './view-controller';
|
import { ViewController, isViewController } from './view-controller';
|
||||||
import { Animation, Config, DomController, FrameworkDelegate, GestureDetail, NavOutlet } from '../..';
|
import { Animation, Config, DomController, FrameworkDelegate, GestureDetail, NavOutlet } from '../..';
|
||||||
import { RouteID, RouteWrite } from '../router/utils/interfaces';
|
import { RouteID, RouteWrite } from '../router/utils/interfaces';
|
||||||
|
import { AnimationOptions, ViewLifecycle, lifecycle, transition } from '../../utils/transition';
|
||||||
import { assert } from '../../utils/helpers';
|
import { assert } from '../../utils/helpers';
|
||||||
|
|
||||||
import iosTransitionAnimation from './animations/ios.transition';
|
import iosTransitionAnimation from './animations/ios.transition';
|
||||||
import mdTransitionAnimation from './animations/md.transition';
|
import mdTransitionAnimation from './animations/md.transition';
|
||||||
import { AnimationOptions, ViewLifecycle, lifecycle, transition } from '../../utils/transition';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
tag: 'ion-nav',
|
tag: 'ion-nav',
|
||||||
@ -202,7 +202,7 @@ export class NavControllerBase implements NavOutlet {
|
|||||||
setRouteId(id: string, params: any = {}, direction: number): Promise<RouteWrite> {
|
setRouteId(id: string, params: any = {}, direction: number): Promise<RouteWrite> {
|
||||||
const active = this.getActive();
|
const active = this.getActive();
|
||||||
if (active && active.component === id) {
|
if (active && active.component === id) {
|
||||||
return Promise.resolve({changed: false});
|
return Promise.resolve({changed: false, element: active.element});
|
||||||
}
|
}
|
||||||
const viewController = this._views.find(v => v.component === id) || id;
|
const viewController = this._views.find(v => v.component === id) || id;
|
||||||
|
|
||||||
@ -215,6 +215,7 @@ export class NavControllerBase implements NavOutlet {
|
|||||||
const p = new Promise(r => markVisible = r);
|
const p = new Promise(r => markVisible = r);
|
||||||
resolve({
|
resolve({
|
||||||
changed: true,
|
changed: true,
|
||||||
|
element: this.getActive().element,
|
||||||
markVisible
|
markVisible
|
||||||
});
|
});
|
||||||
return p;
|
return p;
|
||||||
@ -238,22 +239,11 @@ export class NavControllerBase implements NavOutlet {
|
|||||||
@Method()
|
@Method()
|
||||||
getRouteId(): RouteID|undefined {
|
getRouteId(): RouteID|undefined {
|
||||||
const active = this.getActive();
|
const active = this.getActive();
|
||||||
if (active) {
|
return active ? {
|
||||||
return {
|
id: active.element.tagName,
|
||||||
id: active.element.tagName,
|
params: active.data,
|
||||||
params: active.data
|
element: active.element
|
||||||
};
|
} : undefined;
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Method()
|
|
||||||
getContainerEl(): HTMLElement|undefined {
|
|
||||||
const active = this.getActive();
|
|
||||||
if (active) {
|
|
||||||
return active.element;
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Method()
|
@Method()
|
||||||
@ -641,7 +631,6 @@ export class NavControllerBase implements NavOutlet {
|
|||||||
viewIsReady: opts.viewIsReady,
|
viewIsReady: opts.viewIsReady,
|
||||||
|
|
||||||
showGoBack: this.canGoBack(enteringView),
|
showGoBack: this.canGoBack(enteringView),
|
||||||
isRTL: document.dir === 'rtl',
|
|
||||||
progressAnimation,
|
progressAnimation,
|
||||||
baseEl: this.el,
|
baseEl: this.el,
|
||||||
enteringEl,
|
enteringEl,
|
||||||
|
@ -78,9 +78,6 @@ boolean
|
|||||||
#### getByIndex()
|
#### getByIndex()
|
||||||
|
|
||||||
|
|
||||||
#### getContainerEl()
|
|
||||||
|
|
||||||
|
|
||||||
#### getPrevious()
|
#### getPrevious()
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,33 +1,33 @@
|
|||||||
import { NavOutlet, NavOutletElement, RouteChain, RouteID } from './interfaces';
|
import { NavOutlet, NavOutletElement, RouteChain, RouteID } from './interfaces';
|
||||||
|
|
||||||
export function writeNavState(root: HTMLElement, chain: RouteChain|null, index: number, direction: number): Promise<boolean> {
|
export async function writeNavState(root: HTMLElement|undefined, chain: RouteChain|null, index: number, direction: number): Promise<boolean> {
|
||||||
if (!chain || index >= chain.length) {
|
// find next navigation outlet in the DOM
|
||||||
return Promise.resolve(direction === 0);
|
const outlet = searchNavNode(root);
|
||||||
}
|
|
||||||
const route = chain[index];
|
|
||||||
const node = searchNavNode(root);
|
|
||||||
if (!node) {
|
|
||||||
return Promise.resolve(direction === 0);
|
|
||||||
}
|
|
||||||
return node.componentOnReady()
|
|
||||||
.then(() => node.setRouteId(route.id, route.params, direction))
|
|
||||||
.catch(() => ({changed: false, markVisible: undefined}))
|
|
||||||
.then(result => {
|
|
||||||
if (result.changed) {
|
|
||||||
direction = 0;
|
|
||||||
}
|
|
||||||
const nextEl = node.getContainerEl();
|
|
||||||
const promise = (nextEl)
|
|
||||||
? writeNavState(nextEl, chain, index + 1, direction)
|
|
||||||
: Promise.resolve(direction === 0);
|
|
||||||
|
|
||||||
return promise.then((c) => {
|
// make sure we can continue interating the DOM, otherwise abort
|
||||||
if (result.markVisible) {
|
if (!chain || index >= chain.length || !outlet) {
|
||||||
result.markVisible();
|
return direction === 0;
|
||||||
}
|
}
|
||||||
return c;
|
await outlet.componentOnReady();
|
||||||
});
|
|
||||||
});
|
const route = chain[index];
|
||||||
|
const result = await outlet.setRouteId(route.id, route.params, direction);
|
||||||
|
|
||||||
|
// if the outlet changed the page, reset navigation to neutral (no direction)
|
||||||
|
// this means nested outlets will not animate
|
||||||
|
if (result.changed) {
|
||||||
|
direction = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// recursivelly set nested outlets
|
||||||
|
const changed = await writeNavState(result.element, chain, index + 1, direction);
|
||||||
|
|
||||||
|
// once all nested outlets are visible let's make the parent visible too,
|
||||||
|
// using markVisible prevents flickering
|
||||||
|
if (result.markVisible) {
|
||||||
|
await result.markVisible();
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function readNavState(root: HTMLElement) {
|
export function readNavState(root: HTMLElement) {
|
||||||
@ -39,7 +39,8 @@ export function readNavState(root: HTMLElement) {
|
|||||||
if (pivot) {
|
if (pivot) {
|
||||||
const id = pivot.getRouteId();
|
const id = pivot.getRouteId();
|
||||||
if (id) {
|
if (id) {
|
||||||
node = pivot.getContainerEl();
|
node = id.element;
|
||||||
|
id.element = undefined;
|
||||||
ids.push(id);
|
ids.push(id);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
@ -51,7 +52,7 @@ export function readNavState(root: HTMLElement) {
|
|||||||
return {ids, pivot};
|
return {ids, pivot};
|
||||||
}
|
}
|
||||||
|
|
||||||
const QUERY = ':not([no-router]) ion-nav,:not([no-router]) ion-tabs';
|
const QUERY = ':not([no-router]) ion-nav,:not([no-router]) ion-tabs, :not([no-router]) ion-router-outlet';
|
||||||
|
|
||||||
function searchNavNode(root: HTMLElement|undefined): NavOutletElement|null {
|
function searchNavNode(root: HTMLElement|undefined): NavOutletElement|null {
|
||||||
if (!root) {
|
if (!root) {
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
export interface NavOutlet {
|
export interface NavOutlet {
|
||||||
setRouteId(id: string, data: any, direction: number): Promise<RouteWrite>;
|
setRouteId(id: string, data: any, direction: number): Promise<RouteWrite>;
|
||||||
getRouteId(): RouteID|undefined;
|
getRouteId(): RouteID|undefined;
|
||||||
|
|
||||||
getContainerEl(): HTMLElement | undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RouterEventDetail {
|
export interface RouterEventDetail {
|
||||||
@ -19,11 +17,13 @@ export interface RouteRedirect {
|
|||||||
|
|
||||||
export interface RouteWrite {
|
export interface RouteWrite {
|
||||||
changed: boolean;
|
changed: boolean;
|
||||||
|
element: HTMLElement | undefined;
|
||||||
markVisible?: () => void|Promise<void>;
|
markVisible?: () => void|Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RouteID {
|
export interface RouteID {
|
||||||
id: string;
|
id: string;
|
||||||
|
element: HTMLElement|undefined;
|
||||||
params?: any;
|
params?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,9 +222,6 @@ Emitted when the tab changes.
|
|||||||
|
|
||||||
## Methods
|
## Methods
|
||||||
|
|
||||||
#### getContainerEl()
|
|
||||||
|
|
||||||
|
|
||||||
#### getRouteId()
|
#### getRouteId()
|
||||||
|
|
||||||
|
|
||||||
|
@ -78,8 +78,9 @@ export class Tabs implements NavOutlet {
|
|||||||
this.loadConfig('tabsHighlight', true);
|
this.loadConfig('tabsHighlight', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidLoad() {
|
async componentDidLoad() {
|
||||||
return this.initTabs().then(() => this.initSelect());
|
await this.initTabs();
|
||||||
|
await this.initSelect();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUnload() {
|
componentDidUnload() {
|
||||||
@ -97,26 +98,35 @@ export class Tabs implements NavOutlet {
|
|||||||
* @param {number|Tab} tabOrIndex Index, or the Tab instance, of the tab to select.
|
* @param {number|Tab} tabOrIndex Index, or the Tab instance, of the tab to select.
|
||||||
*/
|
*/
|
||||||
@Method()
|
@Method()
|
||||||
select(tabOrIndex: number | HTMLIonTabElement): Promise<boolean> {
|
async select(tabOrIndex: number | HTMLIonTabElement): Promise<boolean> {
|
||||||
const selectedTab = this.getTab(tabOrIndex);
|
const selectedTab = this.getTab(tabOrIndex);
|
||||||
if (!this.shouldSwitch(selectedTab)) {
|
if (!this.shouldSwitch(selectedTab)) {
|
||||||
return Promise.resolve(false);
|
return false;
|
||||||
}
|
}
|
||||||
return this.setActive(selectedTab)
|
await this.setActive(selectedTab);
|
||||||
.then(() => this.notifyRouter())
|
await this.notifyRouter();
|
||||||
.then(() => this.tabSwitch());
|
return this.tabSwitch();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Method()
|
@Method()
|
||||||
setRouteId(id: string): Promise<RouteWrite> {
|
async setRouteId(id: string): Promise<RouteWrite> {
|
||||||
const selectedTab = this.getTab(id);
|
const selectedTab = this.getTab(id);
|
||||||
if (!this.shouldSwitch(selectedTab)) {
|
if (!this.shouldSwitch(selectedTab)) {
|
||||||
return Promise.resolve({changed: false});
|
return {changed: false, element: this.selectedTab};
|
||||||
}
|
}
|
||||||
return this.setActive(selectedTab).then(() => ({
|
|
||||||
|
await this.setActive(selectedTab);
|
||||||
|
return {
|
||||||
changed: true,
|
changed: true,
|
||||||
|
element: this.selectedTab,
|
||||||
markVisible: () => { this.tabSwitch(); }
|
markVisible: () => { this.tabSwitch(); }
|
||||||
}));
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Method()
|
||||||
|
getRouteId(): RouteID|undefined {
|
||||||
|
const id = this.selectedTab && this.selectedTab.getTabId();
|
||||||
|
return id ? {id, element: this.selectedTab} : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Method()
|
@Method()
|
||||||
@ -138,17 +148,6 @@ export class Tabs implements NavOutlet {
|
|||||||
return this.selectedTab;
|
return this.selectedTab;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Method()
|
|
||||||
getRouteId(): RouteID|undefined {
|
|
||||||
const id = this.selectedTab && this.selectedTab.getTabId();
|
|
||||||
return id ? {id} : undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Method()
|
|
||||||
getContainerEl(): HTMLElement|undefined {
|
|
||||||
return this.selectedTab;
|
|
||||||
}
|
|
||||||
|
|
||||||
private initTabs() {
|
private initTabs() {
|
||||||
const tabs = this.tabs = Array.from(this.el.querySelectorAll('ion-tab'));
|
const tabs = this.tabs = Array.from(this.el.querySelectorAll('ion-tab'));
|
||||||
const tabPromises = tabs.map(tab => {
|
const tabPromises = tabs.map(tab => {
|
||||||
@ -161,7 +160,7 @@ export class Tabs implements NavOutlet {
|
|||||||
return Promise.all(tabPromises);
|
return Promise.all(tabPromises);
|
||||||
}
|
}
|
||||||
|
|
||||||
private initSelect(): Promise<void> {
|
private async initSelect(): Promise<void> {
|
||||||
if (this.useRouter) {
|
if (this.useRouter) {
|
||||||
if (Build.isDev) {
|
if (Build.isDev) {
|
||||||
const selectedTab = this.tabs.find(t => t.selected);
|
const selectedTab = this.tabs.find(t => t.selected);
|
||||||
@ -170,7 +169,7 @@ export class Tabs implements NavOutlet {
|
|||||||
'Define routes properly the define which tab is selected');
|
'Define routes properly the define which tab is selected');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Promise.resolve();
|
return;
|
||||||
}
|
}
|
||||||
// find pre-selected tabs
|
// find pre-selected tabs
|
||||||
const selectedTab = this.tabs.find(t => t.selected) ||
|
const selectedTab = this.tabs.find(t => t.selected) ||
|
||||||
@ -182,14 +181,14 @@ export class Tabs implements NavOutlet {
|
|||||||
tab.selected = false;
|
tab.selected = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const promise = selectedTab ? selectedTab.setActive() : Promise.resolve(null);
|
if (selectedTab) {
|
||||||
return promise.then(() => {
|
await selectedTab.setActive();
|
||||||
this.selectedTab = selectedTab;
|
}
|
||||||
if (selectedTab) {
|
this.selectedTab = selectedTab;
|
||||||
selectedTab.selected = true;
|
if (selectedTab) {
|
||||||
selectedTab.active = true;
|
selectedTab.selected = true;
|
||||||
}
|
selectedTab.active = true;
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private loadConfig(attrKey: string, fallback: any) {
|
private loadConfig(attrKey: string, fallback: any) {
|
||||||
|
@ -9,7 +9,7 @@ export async function transition(opts: AnimationOptions): Promise<Animation|void
|
|||||||
|
|
||||||
setZIndex(enteringEl, leavingEl, opts.direction);
|
setZIndex(enteringEl, leavingEl, opts.direction);
|
||||||
showPages(enteringEl, leavingEl);
|
showPages(enteringEl, leavingEl);
|
||||||
showGoBack(enteringEl, opts.showGoBack);
|
showGoBack(enteringEl, !!opts.showGoBack);
|
||||||
|
|
||||||
// fast path for no animation
|
// fast path for no animation
|
||||||
if (!opts.animationBuilder && !opts.animation) {
|
if (!opts.animationBuilder && !opts.animation) {
|
||||||
@ -173,13 +173,12 @@ export const enum ViewLifecycle {
|
|||||||
export interface AnimationOptions {
|
export interface AnimationOptions {
|
||||||
animationCtrl: HTMLIonAnimationControllerElement;
|
animationCtrl: HTMLIonAnimationControllerElement;
|
||||||
animationBuilder: AnimationBuilder;
|
animationBuilder: AnimationBuilder;
|
||||||
animation: Animation|undefined;
|
animation?: Animation;
|
||||||
direction: NavDirection;
|
direction?: NavDirection;
|
||||||
duration: number|undefined;
|
duration?: number;
|
||||||
easing: string|undefined;
|
easing?: string;
|
||||||
isRTL: boolean;
|
viewIsReady?: () => Promise<any>;
|
||||||
showGoBack: boolean;
|
showGoBack?: boolean;
|
||||||
viewIsReady: undefined | (() => Promise<any>);
|
|
||||||
progressAnimation?: Function;
|
progressAnimation?: Function;
|
||||||
enteringEl: HTMLElement;
|
enteringEl: HTMLElement;
|
||||||
leavingEl: HTMLElement;
|
leavingEl: HTMLElement;
|
||||||
|
Reference in New Issue
Block a user