mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-22 05:21:52 +08:00
feat(tabs): adds lazy loading
This commit is contained in:
5
packages/core/src/components.d.ts
vendored
5
packages/core/src/components.d.ts
vendored
@ -40,6 +40,9 @@ import {
|
||||
import {
|
||||
SelectPopoverOption,
|
||||
} from './components/select-popover/select-popover';
|
||||
import {
|
||||
FrameworkDelegate as FrameworkDelegate2,
|
||||
} from '.';
|
||||
import {
|
||||
DomRenderFn,
|
||||
HeaderFn,
|
||||
@ -2995,6 +2998,8 @@ declare global {
|
||||
badge?: string;
|
||||
badgeStyle?: string;
|
||||
btnId?: string;
|
||||
component?: any;
|
||||
delegate?: FrameworkDelegate;
|
||||
disabled?: boolean;
|
||||
icon?: string;
|
||||
path?: string;
|
||||
|
@ -102,7 +102,7 @@ export class Content {
|
||||
});
|
||||
} else {
|
||||
this.cTop = this.cBottom = null;
|
||||
this.dom.write(() => this.scrollEl.removeAttribute('style'));
|
||||
this.dom.write(() => this.scrollEl && this.scrollEl.removeAttribute('style'));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,11 +13,12 @@
|
||||
<ion-app>
|
||||
|
||||
<ion-router>
|
||||
|
||||
<ion-route path="/" component="page-one">
|
||||
<ion-route path="/nested" component="page-nested-one"></ion-route>
|
||||
<ion-route path="/nestes2" component="page-nested-two"></ion-route>
|
||||
</ion-route>
|
||||
|
||||
|
||||
<ion-route path="/two" component="page-two"></ion-route>
|
||||
</ion-router>
|
||||
|
||||
|
@ -88,4 +88,8 @@ export class Router {
|
||||
private readPath(): string[] | null {
|
||||
return readPath(window.location, this.base, this.useHash);
|
||||
}
|
||||
|
||||
render() {
|
||||
return <slot/>;
|
||||
}
|
||||
}
|
||||
|
@ -71,6 +71,18 @@ string
|
||||
Set the root page for this tab.
|
||||
|
||||
|
||||
#### component
|
||||
|
||||
any
|
||||
|
||||
The badge for the tab button.
|
||||
|
||||
|
||||
#### delegate
|
||||
|
||||
|
||||
|
||||
|
||||
#### disabled
|
||||
|
||||
boolean
|
||||
@ -142,6 +154,18 @@ string
|
||||
Set the root page for this tab.
|
||||
|
||||
|
||||
#### component
|
||||
|
||||
any
|
||||
|
||||
The badge for the tab button.
|
||||
|
||||
|
||||
#### delegate
|
||||
|
||||
|
||||
|
||||
|
||||
#### disabled
|
||||
|
||||
boolean
|
||||
|
@ -1,12 +1,14 @@
|
||||
import { Component, Element, Event, EventEmitter, Method, Prop, State, Watch } from '@stencil/core';
|
||||
|
||||
import { getNavAsChildIfExists } from '../../utils/helpers';
|
||||
import { FrameworkDelegate } from '../..';
|
||||
|
||||
@Component({
|
||||
tag: 'ion-tab',
|
||||
})
|
||||
export class Tab {
|
||||
|
||||
private loaded = false;
|
||||
@Element() el: HTMLElement;
|
||||
|
||||
@State() init = false;
|
||||
@ -37,6 +39,11 @@ export class Tab {
|
||||
*/
|
||||
@Prop() badge: string;
|
||||
|
||||
/**
|
||||
* The badge for the tab button.
|
||||
*/
|
||||
@Prop() component: any;
|
||||
|
||||
/**
|
||||
* The badge color for the tab button.
|
||||
*/
|
||||
@ -58,6 +65,7 @@ export class Tab {
|
||||
*/
|
||||
@Prop() tabsHideOnSubPages = false;
|
||||
|
||||
@Prop() delegate: FrameworkDelegate;
|
||||
|
||||
@Prop({ mutable: true }) selected = false;
|
||||
|
||||
@ -76,6 +84,25 @@ export class Tab {
|
||||
@Method()
|
||||
setActive(active: boolean): Promise<any> {
|
||||
this.active = active;
|
||||
if (this.loaded || !active) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
this.loaded = true;
|
||||
|
||||
let promise: Promise<any>;
|
||||
if (this.component) {
|
||||
promise = (this.delegate)
|
||||
? this.delegate.attachViewToDom(this.el, this.component)
|
||||
: attachViewToDom(this.el, this.component);
|
||||
|
||||
} else {
|
||||
promise = Promise.resolve();
|
||||
}
|
||||
return promise.then(() => this.fireChildren());
|
||||
}
|
||||
|
||||
fireChildren() {
|
||||
const nav = getNavAsChildIfExists(this.el);
|
||||
if (nav && nav.getViews().length === 0 && nav.root) {
|
||||
// we need to initialize
|
||||
@ -99,7 +126,7 @@ export class Tab {
|
||||
hostData() {
|
||||
const visible = this.active && this.selected;
|
||||
return {
|
||||
'aria-hidden': !visible ? 'true' : null,
|
||||
'aria-hidden': !visible,
|
||||
'aria-labelledby': this.btnId,
|
||||
'role': 'tabpanel',
|
||||
class: {
|
||||
@ -109,10 +136,19 @@ export class Tab {
|
||||
}
|
||||
|
||||
render() {
|
||||
return <slot></slot>;
|
||||
return <slot/>;
|
||||
}
|
||||
}
|
||||
|
||||
function attachViewToDom(container: HTMLElement, cmp: string): Promise<any> {
|
||||
const el = document.createElement(cmp) as HTMLStencilElement;
|
||||
container.appendChild(el);
|
||||
if (el.componentOnReady ) {
|
||||
return el.componentOnReady();
|
||||
}
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
export interface TabEvent extends CustomEvent {
|
||||
detail: TabEventDetail;
|
||||
}
|
||||
|
@ -5,9 +5,7 @@
|
||||
<title>Tab - Basic</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
|
||||
<script src="/dist/ionic.js"></script>
|
||||
<script type="text/javascript">
|
||||
window.Ionic.config = {useRouter: true};
|
||||
</script>
|
||||
<script src="/test-components/build/app.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@ -52,17 +50,11 @@
|
||||
</ion-page>
|
||||
</ion-tab>
|
||||
|
||||
<ion-tab title="Messages" icon="chatboxes" path="tab4">
|
||||
<ion-page>
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Tab Four</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content padding>
|
||||
Tab Four
|
||||
</ion-content>
|
||||
</ion-page>
|
||||
<ion-tab
|
||||
title="Messages"
|
||||
icon="chatboxes"
|
||||
component="page-one"
|
||||
path="tab4">
|
||||
</ion-tab>
|
||||
</ion-tabs>
|
||||
</ion-app>
|
||||
|
Reference in New Issue
Block a user