fix(all): component reusage (#18963)

Use new stencil APIs to allow ionic elements to be reused once removed from the DOM.

fixes #18843
fixes #17344
fixes #16453
fixes #15879
fixes #15788
fixes #15484
fixes #17890
fixes #16364
This commit is contained in:
Manu MA
2019-08-27 16:29:37 +02:00
committed by GitHub
parent a65d897214
commit 48a27636c7
33 changed files with 411 additions and 368 deletions

View File

@ -19,7 +19,6 @@ export class Tabs implements NavOutlet {
@Element() el!: HTMLIonTabsElement;
@State() tabs: HTMLIonTabElement[] = [];
@State() selectedTab?: HTMLIonTabElement;
/** @internal */
@ -41,23 +40,18 @@ export class Tabs implements NavOutlet {
*/
@Event({ bubbles: false }) ionTabsDidChange!: EventEmitter<{tab: string}>;
componentWillLoad() {
async componentWillLoad() {
if (!this.useRouter) {
this.useRouter = !!document.querySelector('ion-router') && !this.el.closest('[no-router]');
}
this.tabs = Array.from(this.el.querySelectorAll('ion-tab'));
this.initSelect().then(() => {
this.ionNavWillLoad.emit();
this.componentWillUpdate();
});
if (!this.useRouter) {
const tabs = this.tabs;
await this.select(tabs[0]);
}
this.ionNavWillLoad.emit();
}
componentDidUnload() {
this.tabs.length = 0;
this.selectedTab = this.leavingTab = undefined;
}
componentWillUpdate() {
componentWillRender() {
const tabBar = this.el.querySelector('ion-tab-bar');
if (tabBar) {
const tab = this.selectedTab ? this.selectedTab.tab : undefined;
@ -131,16 +125,6 @@ export class Tabs implements NavOutlet {
return tabId !== undefined ? { id: tabId, element: this.selectedTab } : undefined;
}
private async initSelect(): Promise<void> {
if (this.useRouter) {
return;
}
// wait for all tabs to be ready
await Promise.all(this.tabs.map(tab => tab.componentOnReady()));
await this.select(this.tabs[0]);
}
private setActive(selectedTab: HTMLIonTabElement): Promise<void> {
if (this.transitioning) {
return Promise.reject('transitioning already happening');
@ -186,16 +170,19 @@ export class Tabs implements NavOutlet {
return selectedTab !== undefined && selectedTab !== leavingTab && !this.transitioning;
}
private get tabs() {
return Array.from(this.el.querySelectorAll('ion-tab'));
}
private onTabClicked = (ev: CustomEvent<TabButtonClickEventDetail>) => {
const { href, tab } = ev.detail;
const selectedTab = this.tabs.find(t => t.tab === tab);
if (this.useRouter && href !== undefined) {
const router = document.querySelector('ion-router');
if (router) {
router.push(href);
}
} else if (selectedTab) {
this.select(selectedTab);
} else {
this.select(tab);
}
}