mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
fix(routing): flickering (part 1)
This commit is contained in:
@@ -223,6 +223,11 @@ export class NavControllerBase implements NavOutlet {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Method()
|
||||
markVisible() {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
@Method()
|
||||
getContentElement(): HTMLElement {
|
||||
const active = this.getActive();
|
||||
|
||||
@@ -71,6 +71,9 @@ Return a view controller
|
||||
#### insertPages()
|
||||
|
||||
|
||||
#### markVisible()
|
||||
|
||||
|
||||
#### pop()
|
||||
|
||||
|
||||
|
||||
@@ -18,9 +18,11 @@ export function writeNavState(root: HTMLElement, chain: RouteChain, index: numbe
|
||||
}
|
||||
const nextEl = node.getContentElement();
|
||||
if (nextEl) {
|
||||
return writeNavState(nextEl, chain, index + 1, direction);
|
||||
return writeNavState(nextEl, chain, index + 1, direction)
|
||||
.then(() => node.markVisible());
|
||||
} else {
|
||||
return node.markVisible();
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
|
||||
export interface NavOutlet {
|
||||
setRouteId(id: any, data: any, direction: number): Promise<boolean>;
|
||||
markVisible(): Promise<void>;
|
||||
getRouteId(): string;
|
||||
|
||||
getContentElement(): HTMLElement | null;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import { asyncRaf } from '../../utils/helpers';
|
||||
export class Tab {
|
||||
|
||||
private loaded = false;
|
||||
@Element() el: HTMLElement;
|
||||
@Element() el: HTMLIonTabElement;
|
||||
|
||||
@State() init = false;
|
||||
|
||||
@@ -92,7 +92,7 @@ export class Tab {
|
||||
}
|
||||
|
||||
@Method()
|
||||
setActive(): Promise<any> {
|
||||
setActive(): Promise<HTMLIonTabElement> {
|
||||
return this.prepareLazyLoaded().then(() => this.showTab());
|
||||
}
|
||||
|
||||
@@ -104,9 +104,9 @@ export class Tab {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
private showTab(): Promise<any|void> {
|
||||
private showTab(): Promise<HTMLIonTabElement> {
|
||||
this.active = true;
|
||||
return Promise.resolve();
|
||||
return Promise.resolve(this.el);
|
||||
}
|
||||
|
||||
hostData() {
|
||||
|
||||
@@ -240,6 +240,9 @@ Emitted when the tab changes.
|
||||
#### getTabs()
|
||||
|
||||
|
||||
#### markVisible()
|
||||
|
||||
|
||||
#### select()
|
||||
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ import { Config, NavOutlet } from '../../index';
|
||||
export class Tabs implements NavOutlet {
|
||||
private ids = -1;
|
||||
private transitioning = false;
|
||||
private routingView: HTMLIonTabElement;
|
||||
|
||||
private tabsId: number = (++tabIds);
|
||||
|
||||
@Element() el: HTMLElement;
|
||||
@@ -73,10 +75,7 @@ export class Tabs implements NavOutlet {
|
||||
}
|
||||
|
||||
componentDidLoad() {
|
||||
return this.initTabs().then(() => {
|
||||
const useRouter = !!document.querySelector('ion-router');
|
||||
return useRouter ? this.initSelect() : Promise.resolve();
|
||||
});
|
||||
return this.initTabs().then(() => this.initSelect());
|
||||
}
|
||||
|
||||
componentDidUnload() {
|
||||
@@ -95,37 +94,8 @@ export class Tabs implements NavOutlet {
|
||||
*/
|
||||
@Method()
|
||||
select(tabOrIndex: number | HTMLIonTabElement): Promise<boolean> {
|
||||
if (this.transitioning) {
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
const selectedTab = (typeof tabOrIndex === 'number' ? this.getByIndex(tabOrIndex) : tabOrIndex);
|
||||
if (!selectedTab) {
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
|
||||
// Reset rest of tabs
|
||||
for (const tab of this.tabs) {
|
||||
if (selectedTab !== tab) {
|
||||
tab.selected = false;
|
||||
}
|
||||
}
|
||||
|
||||
const leavingTab = this.selectedTab;
|
||||
this.transitioning = true;
|
||||
return selectedTab.setActive().then(() => {
|
||||
this.transitioning = false;
|
||||
selectedTab.selected = true;
|
||||
if (leavingTab !== selectedTab) {
|
||||
if (leavingTab) {
|
||||
leavingTab.active = false;
|
||||
}
|
||||
this.selectedTab = selectedTab;
|
||||
this.ionChange.emit(selectedTab);
|
||||
this.ionNavChanged.emit({isPop: false});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
return this.setActive(tabOrIndex)
|
||||
.then(selectedTab => this.tabSwitch(selectedTab));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -161,9 +131,18 @@ export class Tabs implements NavOutlet {
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
const tab = this.tabs.find(t => id === t.getRouteId());
|
||||
return this.select(tab).then(() => true);
|
||||
return this.setActive(tab).then(() => {
|
||||
this.routingView = tab;
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@Method()
|
||||
markVisible(): Promise<void> {
|
||||
this.tabSwitch(this.routingView);
|
||||
this.routingView = null;
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
@Method()
|
||||
getRouteId(): string|null {
|
||||
@@ -176,7 +155,7 @@ export class Tabs implements NavOutlet {
|
||||
|
||||
@Method()
|
||||
getContentElement(): HTMLElement {
|
||||
return this.selectedTab;
|
||||
return this.routingView || this.selectedTab;
|
||||
}
|
||||
|
||||
private initTabs() {
|
||||
@@ -191,7 +170,7 @@ export class Tabs implements NavOutlet {
|
||||
return Promise.all(tabPromises);
|
||||
}
|
||||
|
||||
private initSelect() {
|
||||
private initSelect(): Promise<void> {
|
||||
if (document.querySelector('ion-router')) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
@@ -205,7 +184,7 @@ export class Tabs implements NavOutlet {
|
||||
tab.selected = false;
|
||||
}
|
||||
}
|
||||
const promise = selectedTab ? selectedTab.setActive() : Promise.resolve();
|
||||
const promise = selectedTab ? selectedTab.setActive() : Promise.resolve(null);
|
||||
return promise.then(() => {
|
||||
this.selectedTab = selectedTab;
|
||||
if (selectedTab) {
|
||||
@@ -222,6 +201,45 @@ export class Tabs implements NavOutlet {
|
||||
}
|
||||
}
|
||||
|
||||
private setActive(tabOrIndex: number | HTMLIonTabElement): Promise<HTMLIonTabElement|null> {
|
||||
if (this.transitioning) {
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
const selectedTab = (typeof tabOrIndex === 'number' ? this.getByIndex(tabOrIndex) : tabOrIndex);
|
||||
if (!selectedTab) {
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
|
||||
// Reset rest of tabs
|
||||
for (const tab of this.tabs) {
|
||||
if (selectedTab !== tab) {
|
||||
tab.selected = false;
|
||||
}
|
||||
}
|
||||
|
||||
this.transitioning = true;
|
||||
return selectedTab.setActive();
|
||||
}
|
||||
|
||||
private tabSwitch(selectedTab: HTMLIonTabElement | null): boolean {
|
||||
this.transitioning = false;
|
||||
if (!selectedTab) {
|
||||
return false;
|
||||
}
|
||||
const leavingTab = this.selectedTab;
|
||||
selectedTab.selected = true;
|
||||
if (leavingTab !== selectedTab) {
|
||||
if (leavingTab) {
|
||||
leavingTab.active = false;
|
||||
}
|
||||
this.selectedTab = selectedTab;
|
||||
this.ionChange.emit(selectedTab);
|
||||
this.ionNavChanged.emit({isPop: false});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
render() {
|
||||
const dom = [
|
||||
<div class='tabs-inner'>
|
||||
|
||||
Reference in New Issue
Block a user