feat(tabs): adds lazy loading

This commit is contained in:
Manu Mtz.-Almeida
2018-02-08 17:05:16 +01:00
parent cdba38d004
commit 74cce164a3
7 changed files with 80 additions and 18 deletions

View File

@ -40,6 +40,9 @@ import {
import { import {
SelectPopoverOption, SelectPopoverOption,
} from './components/select-popover/select-popover'; } from './components/select-popover/select-popover';
import {
FrameworkDelegate as FrameworkDelegate2,
} from '.';
import { import {
DomRenderFn, DomRenderFn,
HeaderFn, HeaderFn,
@ -2995,6 +2998,8 @@ declare global {
badge?: string; badge?: string;
badgeStyle?: string; badgeStyle?: string;
btnId?: string; btnId?: string;
component?: any;
delegate?: FrameworkDelegate;
disabled?: boolean; disabled?: boolean;
icon?: string; icon?: string;
path?: string; path?: string;

View File

@ -102,7 +102,7 @@ export class Content {
}); });
} else { } else {
this.cTop = this.cBottom = null; this.cTop = this.cBottom = null;
this.dom.write(() => this.scrollEl.removeAttribute('style')); this.dom.write(() => this.scrollEl && this.scrollEl.removeAttribute('style'));
} }
} }

View File

@ -13,6 +13,7 @@
<ion-app> <ion-app>
<ion-router> <ion-router>
<ion-route path="/" component="page-one"> <ion-route path="/" component="page-one">
<ion-route path="/nested" component="page-nested-one"></ion-route> <ion-route path="/nested" component="page-nested-one"></ion-route>
<ion-route path="/nestes2" component="page-nested-two"></ion-route> <ion-route path="/nestes2" component="page-nested-two"></ion-route>

View File

@ -88,4 +88,8 @@ export class Router {
private readPath(): string[] | null { private readPath(): string[] | null {
return readPath(window.location, this.base, this.useHash); return readPath(window.location, this.base, this.useHash);
} }
render() {
return <slot/>;
}
} }

View File

@ -71,6 +71,18 @@ string
Set the root page for this tab. Set the root page for this tab.
#### component
any
The badge for the tab button.
#### delegate
#### disabled #### disabled
boolean boolean
@ -142,6 +154,18 @@ string
Set the root page for this tab. Set the root page for this tab.
#### component
any
The badge for the tab button.
#### delegate
#### disabled #### disabled
boolean boolean

View File

@ -1,12 +1,14 @@
import { Component, Element, Event, EventEmitter, Method, Prop, State, Watch } from '@stencil/core'; import { Component, Element, Event, EventEmitter, Method, Prop, State, Watch } from '@stencil/core';
import { getNavAsChildIfExists } from '../../utils/helpers'; import { getNavAsChildIfExists } from '../../utils/helpers';
import { FrameworkDelegate } from '../..';
@Component({ @Component({
tag: 'ion-tab', tag: 'ion-tab',
}) })
export class Tab { export class Tab {
private loaded = false;
@Element() el: HTMLElement; @Element() el: HTMLElement;
@State() init = false; @State() init = false;
@ -37,6 +39,11 @@ export class Tab {
*/ */
@Prop() badge: string; @Prop() badge: string;
/**
* The badge for the tab button.
*/
@Prop() component: any;
/** /**
* The badge color for the tab button. * The badge color for the tab button.
*/ */
@ -58,6 +65,7 @@ export class Tab {
*/ */
@Prop() tabsHideOnSubPages = false; @Prop() tabsHideOnSubPages = false;
@Prop() delegate: FrameworkDelegate;
@Prop({ mutable: true }) selected = false; @Prop({ mutable: true }) selected = false;
@ -76,6 +84,25 @@ export class Tab {
@Method() @Method()
setActive(active: boolean): Promise<any> { setActive(active: boolean): Promise<any> {
this.active = active; 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); const nav = getNavAsChildIfExists(this.el);
if (nav && nav.getViews().length === 0 && nav.root) { if (nav && nav.getViews().length === 0 && nav.root) {
// we need to initialize // we need to initialize
@ -99,7 +126,7 @@ export class Tab {
hostData() { hostData() {
const visible = this.active && this.selected; const visible = this.active && this.selected;
return { return {
'aria-hidden': !visible ? 'true' : null, 'aria-hidden': !visible,
'aria-labelledby': this.btnId, 'aria-labelledby': this.btnId,
'role': 'tabpanel', 'role': 'tabpanel',
class: { class: {
@ -109,10 +136,19 @@ export class Tab {
} }
render() { 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 { export interface TabEvent extends CustomEvent {
detail: TabEventDetail; detail: TabEventDetail;
} }

View File

@ -5,9 +5,7 @@
<title>Tab - Basic</title> <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"> <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 src="/dist/ionic.js"></script>
<script type="text/javascript"> <script src="/test-components/build/app.js"></script>
window.Ionic.config = {useRouter: true};
</script>
</head> </head>
<body> <body>
@ -52,17 +50,11 @@
</ion-page> </ion-page>
</ion-tab> </ion-tab>
<ion-tab title="Messages" icon="chatboxes" path="tab4"> <ion-tab
<ion-page> title="Messages"
<ion-header> icon="chatboxes"
<ion-toolbar> component="page-one"
<ion-title>Tab Four</ion-title> path="tab4">
</ion-toolbar>
</ion-header>
<ion-content padding>
Tab Four
</ion-content>
</ion-page>
</ion-tab> </ion-tab>
</ion-tabs> </ion-tabs>
</ion-app> </ion-app>