/
githubmirror
/
ionic-framework
Обзор
Документация
Войти
/
githubmirror
/
ionic-framework
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
core/src/components/tab/tab.tsx
104 строки
3 KB
Shane
fix(tab): retry lazy load after a failed attach (#31324)
05 авг 2026, 19:02
Не верифицирован
05 авг 2026, 19:02
81b52e2
Код
Авторство
О чём код?
import type { ComponentInterface } from '@stencil/core'; import { Build, Component, Element, Host, Method, Prop, Watch, h } from '@stencil/core'; import { attachComponent } from '@utils/framework-delegate'; import { printIonError } from '@utils/logging'; import type { ComponentRef, FrameworkDelegate } from '../../interface'; @Component({ tag: 'ion-tab', styleUrl: 'tab.scss', shadow: true, }) export class Tab implements ComponentInterface { private loadPromise?: Promise<HTMLElement | undefined>; @Element() el!: HTMLIonTabElement; /** @internal */ @Prop({ mutable: true }) active = false; /** @internal */ @Prop() delegate?: FrameworkDelegate; /** * A tab id must be provided for each `ion-tab`. It's used internally to reference * the selected tab or by the router to switch between them. */ @Prop() tab!: string; /** * The component to display inside of the tab. */ @Prop() component?: ComponentRef; async componentWillLoad() { if (Build.isDev) { if (this.component !== undefined && this.el.childElementCount > 0) { printIonError( '[ion-tab] - You can not use a lazy-loaded component in a tab and inlined content at the same time.' + `- Remove the component attribute in: <ion-tab component="${this.component}">` + ` or` + `- Remove the embedded content inside the ion-tab: <ion-tab></ion-tab>` ); } } if (this.active) { await this.setActive(); } } /** Set the active component for the tab */ @Method() async setActive(): Promise<void> { await this.prepareLazyLoaded(); this.active = true; } @Watch('active') changeActive(isActive: boolean) { if (isActive) { this.prepareLazyLoaded().catch((e) => { printIonError('[ion-tab] - Exception in prepareLazyLoaded:', e); }); } } private prepareLazyLoaded(): Promise<HTMLElement | undefined> { if (this.component == null) { return Promise.resolve(undefined); } /** * The attach is cached so that concurrent activations share a single * attempt and later activations reuse the result. The cache is cleared * only when the attach fails, so a tab whose component failed to load * can be retried the next time it is activated. */ if (this.loadPromise === undefined) { this.loadPromise = attachComponent(this.delegate, this.el, this.component, ['ion-page']).catch((e) => { this.loadPromise = undefined; throw e; }); } return this.loadPromise; } render() { const { tab, active, component } = this; return ( <Host role="tabpanel" aria-hidden={!active ? 'true' : null} aria-labelledby={`tab-button-${tab}`} class={{ 'ion-page': component === undefined, 'tab-hidden': !active, }} > <slot></slot> </Host> ); } }