fix(virtual-scroll): working in angular

This commit is contained in:
Manu Mtz.-Almeida
2018-02-01 22:18:19 +01:00
parent c189094f64
commit 0babb2ece2
20 changed files with 313 additions and 164 deletions

View File

@ -5,27 +5,27 @@
"requires": true,
"dependencies": {
"@angular/common": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/@angular/common/-/common-5.2.2.tgz",
"integrity": "sha512-heon7Bdu6SUw/6ma9wEDxrxBJY2V+NSUv7ZVY7HaXESWvxKUGaser5vQIsWghvBg1injSxyw/3BqGFflua/3sQ==",
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/@angular/common/-/common-5.2.3.tgz",
"integrity": "sha512-RwQ/IjmpDdMecTz/wwQlKpHgF4Crr8kyqV9FJ+c+cHR8Riqlu2DOXSU7LIfDdGoo6Mpixdxd1rtHYfs7l9YBSA==",
"dev": true,
"requires": {
"tslib": "1.9.0"
}
},
"@angular/compiler": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-5.2.2.tgz",
"integrity": "sha512-QkliIJJb9J2y4Y1yiSweP1eOStClOOOj46awVQ5wT+WzyvmIVAccx2u+r5TPRu676GlqrFfn6FD+zV6Zw7G+Tw==",
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-5.2.3.tgz",
"integrity": "sha512-OynSzUdEHwajQMoV2JuYq5IdiR2dlTCTAHhTLzrym85wOihvTvovEQwVhYYHyKERu85JIoaF1sXA42KIjMGfkw==",
"dev": true,
"requires": {
"tslib": "1.9.0"
}
},
"@angular/compiler-cli": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-5.2.2.tgz",
"integrity": "sha512-XSojPIMQNvEnYIufTIlrr3GLpr20AUQP0bMzUp4/U/ATWmMWmdNRRG/ys5ncmbgImoAg1nW0hp4bonUSYf9nGQ==",
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-5.2.3.tgz",
"integrity": "sha512-uoCxeyQSd8R/cwEbd0FIUXjnbPq0HXEsyu3WSu9Ek2jt52HL+x/gZQdFCRtjW/mvQNOqxrgrTtEkhJ398+VkXg==",
"dev": true,
"requires": {
"chokidar": "1.7.0",
@ -162,45 +162,45 @@
}
},
"@angular/core": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/@angular/core/-/core-5.2.2.tgz",
"integrity": "sha512-SycTFvlJUHzYvqRYM0DQQUewSo0IPL3Vfo9MOwSJvhS5mXCP1+QW0IIhI8CyWy+40L3dIWlYnn0754z5IJikdg==",
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/@angular/core/-/core-5.2.3.tgz",
"integrity": "sha512-tL9O8KA6KGjnlxqjuTytpC2OeKbxe/yHev0kmwo5CK0lDZU4UFetcItAzUXU1dyRuILTcBkbnFt9+nr1SZs/cQ==",
"dev": true,
"requires": {
"tslib": "1.9.0"
}
},
"@angular/forms": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/@angular/forms/-/forms-5.2.2.tgz",
"integrity": "sha512-mvY3p0s7TDfc78tHFID11N1UF+5HZNy26poujOTI2q5m0BgM2JskFaQxWBdLT0OLutqV6NYeaHXUwmqsD4TGVg==",
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/@angular/forms/-/forms-5.2.3.tgz",
"integrity": "sha512-PsMGbj/Slvsxxyl61QSSSFDCGHN1XK6kNxVQTVmAlVhP1LlaYqBOIgQy4K9CYWUeHqU/YCdhVaFb5quzZLtPYA==",
"dev": true,
"requires": {
"tslib": "1.9.0"
}
},
"@angular/http": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/@angular/http/-/http-5.2.2.tgz",
"integrity": "sha512-MG7ClwOs9gQgAIjKa6WulUmLyWmKbY8qwX1osVn4cTuGtnpcyTiqruOwrS3DzY6doE8qsu2y5VURt3Ncs0SE6Q==",
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/@angular/http/-/http-5.2.3.tgz",
"integrity": "sha512-3kAj7YYws8J2zRu46fEXk6lYrgSK9s5YA6O4REZkLox/suK0wb6TsDIIhoMzScGctSzZESVyuWsvYMrDYCflPA==",
"dev": true,
"requires": {
"tslib": "1.9.0"
}
},
"@angular/platform-browser": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-5.2.2.tgz",
"integrity": "sha512-jiiEEUiv4oOWtBP96hOnxHOY3ckukfSOaxtw+ENjSPAyv/eRbL1B2LFwIg+HYAFxvK8JOLAYZm3Hg9lpenlBMw==",
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-5.2.3.tgz",
"integrity": "sha512-60LgA4KK3BufBR7vwwcn3zTYuLlfDG3jFip7bvdgsDpURrUB0j6/pL5cbGElww4jnnxZ72uJzJRzSiGEofjc3g==",
"dev": true,
"requires": {
"tslib": "1.9.0"
}
},
"@angular/platform-browser-dynamic": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-5.2.2.tgz",
"integrity": "sha512-PCg63japwHw6zGWGHZEpiDKeqPaCbOKnBl7bhRzE5imL+74toyvmE33sp7OzXKGi0mX5mUymfRsvfLdB6khGTQ==",
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-5.2.3.tgz",
"integrity": "sha512-PheS+KJQJiyvQg1lr+eX0/1b/rjLnDjgI1qvzwikrvGYymb2JdZ+rjllHBs1iotzQ+tG+hRnlktvgdFN134x/g==",
"dev": true,
"requires": {
"tslib": "1.9.0"
@ -216,33 +216,33 @@
}
},
"@ionic/core": {
"version": "0.0.2-49",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-0.0.2-49.tgz",
"integrity": "sha512-XEKoKaBHPPwjKcSBJhFNLYtSMJAheng5yUXhpMQQVpprGAPAde4sVHbjAkBZYWDQFNZuMbskeb72EMHSSGVn4w==",
"version": "0.0.2-53",
"resolved": "https://registry.npmjs.org/@ionic/core/-/core-0.0.2-53.tgz",
"integrity": "sha512-AEvDmMrEphcc9tXNvrq96x2aYBB0FuzztNiFnC9QNMbGWtm2Y2eqGO2+nFOip76fClSJV1oJ4Zg0cIynX43U0w==",
"dev": true
},
"@stencil/core": {
"version": "0.3.0-3",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-0.3.0-3.tgz",
"integrity": "sha512-MlN6C5seTM+1Bc5nbSqcLI+FT77lKpQ6q0aw/Eu9awHVLIbVH/xMsr0MZMUJoc0WP2o+SwYuAo7/lIBBnNgFKg==",
"version": "0.3.0-5",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-0.3.0-5.tgz",
"integrity": "sha512-ADK2iPLtziVbGNd6L02W2ablcGPCKGpzhaMytDO2/S7meF7JXM7w8xx24AP6NQM9XD6Ax2lMNkgl8V4A/avLvQ==",
"requires": {
"chokidar": "2.0.0",
"jsdom": "11.5.1",
"node-sass": "4.7.2",
"rollup": "0.55.1",
"rollup": "0.55.3",
"rollup-plugin-commonjs": "8.3.0",
"rollup-plugin-node-builtins": "2.1.2",
"rollup-plugin-node-globals": "1.1.0",
"rollup-plugin-node-resolve": "3.0.2",
"typescript": "2.6.2",
"typescript": "2.7.1",
"uglify-es": "3.3.8",
"workbox-build": "3.0.0-alpha.3"
},
"dependencies": {
"typescript": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.6.2.tgz",
"integrity": "sha1-PFtv1/beCRQmkCfwPAlGdY92c6Q="
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-2.7.1.tgz",
"integrity": "sha512-bqB1yS6o9TNA9ZC/MJxM0FZzPnZdtHj0xWK/IZ5khzVqdpGul/R/EIiHRgFXlwTD7PSIaYVnGKq1QgMCu2mnqw=="
}
}
},
@ -4160,9 +4160,9 @@
}
},
"rollup": {
"version": "0.55.1",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-0.55.1.tgz",
"integrity": "sha512-lV8lBkpA1PXsshgu8zy51QrGPvWDIhZjcShEyMKk/Riobz4xwutSb0TjAtRyS6wtnn5LNVmCL7KIj4pirOhEdw=="
"version": "0.55.3",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-0.55.3.tgz",
"integrity": "sha512-2TgimJ7pk+XfPT0DmAcOqq9qdXlJ04qKyzyLm1WvPS/E6XdXEXyG5u6L8AsjxOaKoEBlYGliPzo99jxwhn2NYQ=="
},
"rollup-plugin-commonjs": {
"version": "8.3.0",

View File

@ -0,0 +1,10 @@
import { Directive, TemplateRef } from '@angular/core';
import { VirtualContext } from './virtual-utils';
/**
* @hidden
*/
@Directive({selector: '[virtualFooter]'})
export class VirtualFooter {
constructor(public templateRef: TemplateRef<VirtualContext>) {}
}

View File

@ -0,0 +1,10 @@
import { Directive, TemplateRef } from '@angular/core';
import { VirtualContext } from './virtual-utils';
/**
* @hidden
*/
@Directive({selector: '[virtualHeader]'})
export class VirtualHeader {
constructor(public templateRef: TemplateRef<VirtualContext>) {}
}

View File

@ -0,0 +1,10 @@
import { Directive, TemplateRef, ViewContainerRef } from '@angular/core';
import { VirtualContext } from './virtual-utils';
/**
* @hidden
*/
@Directive({selector: '[virtualItem]'})
export class VirtualItem {
constructor(public templateRef: TemplateRef<VirtualContext>, public viewContainer: ViewContainerRef) {}
}

View File

@ -0,0 +1,54 @@
import { EmbeddedViewRef, AfterContentInit, ContentChild, Directive, ElementRef, Input, IterableDiffers, TrackByFunction } from '@angular/core';
import { VirtualItem } from './virtual-item';
import { VirtualHeader } from './virtual-header';
import { VirtualFooter } from './virtual-footer';
import { VirtualContext } from './virtual-utils';
@Directive({
selector: 'ion-virtual-scroll'
})
export class VirtualScroll {
@ContentChild(VirtualItem) itmTmp: VirtualItem;
@ContentChild(VirtualHeader) hdrTmp: VirtualHeader;
@ContentChild(VirtualFooter) ftrTmp: VirtualFooter;
constructor(private el: ElementRef) {
this.el.nativeElement.itemRender = this.itemRender.bind(this);
}
private itemRender(el: HTMLElement|null, cell: any, index?: number) {
if (!el) {
const node = this.itmTmp.viewContainer.createEmbeddedView(
this.getComponent(cell.type),
new VirtualContext(null, null, null),
index
);
el = getElement(node);
(el as any)['$ionView'] = node;
}
const ctx = (el as any)['$ionView'].context;
ctx.$implicit = cell.value;
ctx.index = cell.index;
return el;
}
private getComponent(type: number) {
switch(type) {
case 0: return this.itmTmp.templateRef;
case 1: return this.hdrTmp.templateRef;
case 2: return this.ftrTmp.templateRef;
}
return null;
}
}
function getElement(view: EmbeddedViewRef<VirtualContext>): HTMLElement {
const rootNodes = view.rootNodes;
for (var i = 0; i < rootNodes.length; i++) {
if (rootNodes[i].nodeType === 1) {
return rootNodes[i];
}
}
return null;
}

View File

@ -0,0 +1,14 @@
export class VirtualContext {
constructor(public $implicit: any, public index: number, public count: number) { }
get first(): boolean { return this.index === 0; }
get last(): boolean { return this.index === this.count - 1; }
get even(): boolean { return this.index % 2 === 0; }
get odd(): boolean { return !this.even; }
}

View File

@ -2,6 +2,10 @@ export { IonicAngularModule } from './module';
/* Directives */
export { MenuToggle } from './directives/menu-toggle';
export { VirtualScroll } from './directives/virtual-scroll';
export { VirtualItem } from './directives/virtual-item';
export { VirtualHeader } from './directives/virtual-header';
export { VirtualFooter } from './directives/virtual-footer';
/* Nav */
export { IonNav } from './nav/ion-nav';

View File

@ -18,6 +18,12 @@ import { TextValueAccessor } from './control-value-accessors/text-value-accessor
/* Directives */
import { MenuToggle } from './directives/menu-toggle';
import { VirtualScroll } from './directives/virtual-scroll';
import { VirtualItem } from './directives/virtual-item';
import { VirtualHeader } from './directives/virtual-header';
import { VirtualFooter } from './directives/virtual-footer';
/* Providers */
import { ActionSheetController } from './providers/action-sheet-controller';
import { AlertController } from './providers/alert-controller';
@ -37,7 +43,12 @@ import { ToastController } from './providers/toast-controller';
NumericValueAccessor,
RadioValueAccessor,
SelectValueAccessor,
TextValueAccessor
TextValueAccessor,
VirtualScroll,
VirtualItem,
VirtualHeader,
VirtualFooter,
],
exports: [
BooleanValueAccessor,
@ -45,7 +56,12 @@ import { ToastController } from './providers/toast-controller';
NumericValueAccessor,
RadioValueAccessor,
SelectValueAccessor,
TextValueAccessor
TextValueAccessor,
VirtualScroll,
VirtualItem,
VirtualHeader,
VirtualFooter,
],
imports: [
CommonModule,

View File

@ -53,9 +53,9 @@
return el;
}
virtual.itemRender = (el, item, type) => {
if (type === 0) return renderItem(el, item);
return renderHeader(el, item);
virtual.itemRender = (el, cell) => {
if (cell.type === 0) return renderItem(el, cell.value);
return renderHeader(el, cell.value);
};
virtual.items = Array.from({length: 1000}, (x, i) => i);
};

View File

@ -61,9 +61,9 @@
return el;
}
virtual.itemRender = (el, item, type) => {
if (type === 0) return renderItem(el, item);
return renderHeader(el, item);
virtual.itemRender = (el, cell) => {
if (cell.type === 0) return renderItem(el, cell.value);
return renderHeader(el, cell.value);
};

View File

@ -25,7 +25,7 @@ export interface VirtualNode {
export type NodeHeightFn = (node: VirtualNode, index: number) => number;
export type HeaderFn = (item: any, index: number, items: any[]) => string | null;
export type ItemHeightFn = (item: any, index?: number) => number;
export type ItemRenderFn = (el: HTMLElement|null, item: any, type: CellType, index?: number) => HTMLElement;
export type ItemRenderFn = (el: HTMLElement|null, cell: Cell, domIndex?: number) => HTMLElement;
export type DomRenderFn = (dom: VirtualNode[], height: number) => void;
export function updateVDom(dom: VirtualNode[], heightIndex: Uint32Array, cells: Cell[], top: number, bottom: number) {
@ -84,9 +84,9 @@ export function doRender(el: HTMLElement, itemRender: ItemRenderFn, dom: Virtual
if (node.change === 2) {
if (i < children.length) {
child = children[i] as HTMLElement;
itemRender(child, cell.value, cell.type, cell.index);
itemRender(child, cell, i);
} else {
child = itemRender(null, cell.value, cell.type, cell.index);
child = itemRender(null, cell, i);
child.classList.add('virtual-item');
el.appendChild(child);
}

View File

@ -235,7 +235,7 @@ export class VirtualScroll {
private updateState() {
const shouldEnable = !!(
this.scrollEl &&
this.items &&
this.cells &&
(this.itemRender || this.domRender) &&
this.viewportHeight > 1
);

View File

@ -174,24 +174,24 @@
}
},
"@angular/animations": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/@angular/animations/-/animations-5.2.2.tgz",
"integrity": "sha512-VlnsvvTub7MJqKcyllNHyp6LywUOR8z0uQgTxSXDYcQR39onTRTh9/I7qjRGOZTjNucUojRadyYRMInoPYPgZw==",
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/@angular/animations/-/animations-5.2.3.tgz",
"integrity": "sha512-K9rOsRGwt7Zmp/rNdvBmgBKqvEdgCyZF0kvwxrmZfq1Zj0GAkfTAKPL007493O6XFd+icfu/+kmYeqXBGB4gKA==",
"requires": {
"tslib": "1.9.0"
}
},
"@angular/cli": {
"version": "1.6.6",
"resolved": "https://registry.npmjs.org/@angular/cli/-/cli-1.6.6.tgz",
"integrity": "sha512-+hNKTw8Pcg7RBEsXphpgnebnzlxpbAVW0hRK45iLvjC2550co5sPxxxCikKMjbQzr6LEBhpgGS2ma4jX/AXsCw==",
"version": "1.6.7",
"resolved": "https://registry.npmjs.org/@angular/cli/-/cli-1.6.7.tgz",
"integrity": "sha512-TprSjnQrEdrTsCAB5K/lCLuXZUH/y+l/BAR0aZLpubpZP8Ldgmq7q56trxL5wNSs3o6A8Vh43ZKNYOuKtnzlXQ==",
"dev": true,
"requires": {
"@angular-devkit/build-optimizer": "0.0.42",
"@angular-devkit/core": "0.0.29",
"@angular-devkit/schematics": "0.0.52",
"@ngtools/json-schema": "1.1.0",
"@ngtools/webpack": "1.9.6",
"@ngtools/webpack": "1.9.7",
"@schematics/angular": "0.1.17",
"autoprefixer": "7.2.5",
"chalk": "2.2.2",
@ -232,7 +232,6 @@
"sass-loader": "6.0.6",
"semver": "5.5.0",
"silent-error": "1.1.0",
"source-map-loader": "0.2.3",
"source-map-support": "0.4.18",
"style-loader": "0.13.2",
"stylus": "0.54.5",
@ -289,25 +288,25 @@
}
},
"@angular/common": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/@angular/common/-/common-5.2.2.tgz",
"integrity": "sha512-heon7Bdu6SUw/6ma9wEDxrxBJY2V+NSUv7ZVY7HaXESWvxKUGaser5vQIsWghvBg1injSxyw/3BqGFflua/3sQ==",
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/@angular/common/-/common-5.2.3.tgz",
"integrity": "sha512-RwQ/IjmpDdMecTz/wwQlKpHgF4Crr8kyqV9FJ+c+cHR8Riqlu2DOXSU7LIfDdGoo6Mpixdxd1rtHYfs7l9YBSA==",
"requires": {
"tslib": "1.9.0"
}
},
"@angular/compiler": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-5.2.2.tgz",
"integrity": "sha512-QkliIJJb9J2y4Y1yiSweP1eOStClOOOj46awVQ5wT+WzyvmIVAccx2u+r5TPRu676GlqrFfn6FD+zV6Zw7G+Tw==",
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-5.2.3.tgz",
"integrity": "sha512-OynSzUdEHwajQMoV2JuYq5IdiR2dlTCTAHhTLzrym85wOihvTvovEQwVhYYHyKERu85JIoaF1sXA42KIjMGfkw==",
"requires": {
"tslib": "1.9.0"
}
},
"@angular/compiler-cli": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-5.2.2.tgz",
"integrity": "sha512-XSojPIMQNvEnYIufTIlrr3GLpr20AUQP0bMzUp4/U/ATWmMWmdNRRG/ys5ncmbgImoAg1nW0hp4bonUSYf9nGQ==",
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-5.2.3.tgz",
"integrity": "sha512-uoCxeyQSd8R/cwEbd0FIUXjnbPq0HXEsyu3WSu9Ek2jt52HL+x/gZQdFCRtjW/mvQNOqxrgrTtEkhJ398+VkXg==",
"dev": true,
"requires": {
"chokidar": "1.7.0",
@ -444,55 +443,55 @@
}
},
"@angular/core": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/@angular/core/-/core-5.2.2.tgz",
"integrity": "sha512-SycTFvlJUHzYvqRYM0DQQUewSo0IPL3Vfo9MOwSJvhS5mXCP1+QW0IIhI8CyWy+40L3dIWlYnn0754z5IJikdg==",
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/@angular/core/-/core-5.2.3.tgz",
"integrity": "sha512-tL9O8KA6KGjnlxqjuTytpC2OeKbxe/yHev0kmwo5CK0lDZU4UFetcItAzUXU1dyRuILTcBkbnFt9+nr1SZs/cQ==",
"requires": {
"tslib": "1.9.0"
}
},
"@angular/forms": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/@angular/forms/-/forms-5.2.2.tgz",
"integrity": "sha512-mvY3p0s7TDfc78tHFID11N1UF+5HZNy26poujOTI2q5m0BgM2JskFaQxWBdLT0OLutqV6NYeaHXUwmqsD4TGVg==",
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/@angular/forms/-/forms-5.2.3.tgz",
"integrity": "sha512-PsMGbj/Slvsxxyl61QSSSFDCGHN1XK6kNxVQTVmAlVhP1LlaYqBOIgQy4K9CYWUeHqU/YCdhVaFb5quzZLtPYA==",
"requires": {
"tslib": "1.9.0"
}
},
"@angular/http": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/@angular/http/-/http-5.2.2.tgz",
"integrity": "sha512-MG7ClwOs9gQgAIjKa6WulUmLyWmKbY8qwX1osVn4cTuGtnpcyTiqruOwrS3DzY6doE8qsu2y5VURt3Ncs0SE6Q==",
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/@angular/http/-/http-5.2.3.tgz",
"integrity": "sha512-3kAj7YYws8J2zRu46fEXk6lYrgSK9s5YA6O4REZkLox/suK0wb6TsDIIhoMzScGctSzZESVyuWsvYMrDYCflPA==",
"requires": {
"tslib": "1.9.0"
}
},
"@angular/language-service": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-5.2.2.tgz",
"integrity": "sha512-i+xaMhi/nBoBPi8NUFCWwgUjq9jGgD5y91nkpaBABs+2E5x7LprL1b2hITmfjo1oMY2kY6L7Sihdwp2JhfCVrA==",
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-5.2.3.tgz",
"integrity": "sha512-yBi8i2rUdq6WgYn2J+82QxqhKsl2ldH7/8Lk4ZQDbKgTBx5LmYLpNGg3TJGnZEUGtKhu8Rd1E3SBmc4qqrGXsQ==",
"dev": true
},
"@angular/platform-browser": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-5.2.2.tgz",
"integrity": "sha512-jiiEEUiv4oOWtBP96hOnxHOY3ckukfSOaxtw+ENjSPAyv/eRbL1B2LFwIg+HYAFxvK8JOLAYZm3Hg9lpenlBMw==",
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-5.2.3.tgz",
"integrity": "sha512-60LgA4KK3BufBR7vwwcn3zTYuLlfDG3jFip7bvdgsDpURrUB0j6/pL5cbGElww4jnnxZ72uJzJRzSiGEofjc3g==",
"requires": {
"tslib": "1.9.0"
}
},
"@angular/platform-browser-dynamic": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-5.2.2.tgz",
"integrity": "sha512-PCg63japwHw6zGWGHZEpiDKeqPaCbOKnBl7bhRzE5imL+74toyvmE33sp7OzXKGi0mX5mUymfRsvfLdB6khGTQ==",
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-5.2.3.tgz",
"integrity": "sha512-PheS+KJQJiyvQg1lr+eX0/1b/rjLnDjgI1qvzwikrvGYymb2JdZ+rjllHBs1iotzQ+tG+hRnlktvgdFN134x/g==",
"requires": {
"tslib": "1.9.0"
}
},
"@angular/router": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/@angular/router/-/router-5.2.2.tgz",
"integrity": "sha512-Yn71rFMMyIjwairBWGcUFbdiAVuTp7y5yEin8vJK3DAWgTyk0FYfhKHY3r9NofNH9M7Id53WafC02+3SseFBlA==",
"version": "5.2.3",
"resolved": "https://registry.npmjs.org/@angular/router/-/router-5.2.3.tgz",
"integrity": "sha512-XVEpwNZta76FYas1gZSSGvkQoiGgQjvXfab6CwOh958d4c0C+9pJsykqsv6X/n8TSTShQt7wjs/vp/copXeuoA==",
"requires": {
"tslib": "1.9.0"
}
@ -510,7 +509,7 @@
"resolved": "https://registry.npmjs.org/@ionic/angular/-/angular-0.0.2-21.tgz",
"integrity": "sha512-bAt5RrA+O1gXE5M4qEW2pSJZX6Kbv+fCwZXHFgurT9I9V79na2YVtZHROA2199JR3TTUjkYfMyaAo/pwDDkguQ==",
"requires": {
"@stencil/core": "0.3.0-3"
"@stencil/core": "0.3.0-5"
}
},
"@ionic/core": {
@ -525,9 +524,9 @@
"dev": true
},
"@ngtools/webpack": {
"version": "1.9.6",
"resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-1.9.6.tgz",
"integrity": "sha512-B4a1MlMvnGjT5APYg0mf9oL9OeacVMX0Czl5o5Qps7Hy7FobuY4CwhnCMJAPzy7JXLAEhp6wX8Bqmxj9JJfebA==",
"version": "1.9.7",
"resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-1.9.7.tgz",
"integrity": "sha512-D5QuaT9wENeM2j9g2qvW9Ls1tGqRz26Lp+jxwb2ZGFep7Ik1fFOX3ROLfgkxNlxZGVmbxJjsfrYUCyGlzj8gWg==",
"dev": true,
"requires": {
"chalk": "2.2.2",
@ -589,14 +588,14 @@
}
},
"@stencil/core": {
"version": "0.3.0-3",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-0.3.0-3.tgz",
"integrity": "sha512-MlN6C5seTM+1Bc5nbSqcLI+FT77lKpQ6q0aw/Eu9awHVLIbVH/xMsr0MZMUJoc0WP2o+SwYuAo7/lIBBnNgFKg==",
"version": "0.3.0-5",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-0.3.0-5.tgz",
"integrity": "sha512-ADK2iPLtziVbGNd6L02W2ablcGPCKGpzhaMytDO2/S7meF7JXM7w8xx24AP6NQM9XD6Ax2lMNkgl8V4A/avLvQ==",
"requires": {
"chokidar": "2.0.0",
"jsdom": "11.5.1",
"node-sass": "4.7.2",
"rollup": "0.55.1",
"rollup": "0.55.3",
"rollup-plugin-commonjs": "8.3.0",
"rollup-plugin-node-builtins": "2.1.2",
"rollup-plugin-node-globals": "1.1.0",
@ -675,9 +674,9 @@
}
},
"acorn": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz",
"integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug=="
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-5.4.0.tgz",
"integrity": "sha512-bkLTrtPfRASTxDXFaih7SbeYSsQ8MjrqCQKMrgZ4Hc7kYI//WVU6rDTAIqVrAudjgMFQEGthYfodtaw8dTRJrg=="
},
"acorn-dynamic-import": {
"version": "2.0.2",
@ -701,7 +700,7 @@
"resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.1.0.tgz",
"integrity": "sha512-KjZwU26uG3u6eZcfGbTULzFcsoz6pegNKtHPksZPOUsiKo5bUmiBPa38FuHZ/Eun+XYh/JCCkS9AS3Lu4McQOQ==",
"requires": {
"acorn": "5.3.0"
"acorn": "5.4.0"
}
},
"adm-zip": {
@ -1006,7 +1005,7 @@
"caniuse-lite": "1.0.30000792",
"normalize-range": "0.1.2",
"num2fraction": "1.2.2",
"postcss": "6.0.16",
"postcss": "6.0.17",
"postcss-value-parser": "3.3.0"
}
},
@ -1429,7 +1428,7 @@
"dev": true,
"requires": {
"caniuse-lite": "1.0.30000792",
"electron-to-chromium": "1.3.31"
"electron-to-chromium": "1.3.32"
}
},
"buffer": {
@ -1562,7 +1561,7 @@
"dev": true,
"requires": {
"caniuse-db": "1.0.30000800",
"electron-to-chromium": "1.3.31"
"electron-to-chromium": "1.3.32"
}
}
}
@ -2442,7 +2441,7 @@
"dev": true,
"requires": {
"caniuse-db": "1.0.30000800",
"electron-to-chromium": "1.3.31"
"electron-to-chromium": "1.3.32"
}
},
"has-flag": {
@ -2913,9 +2912,9 @@
"dev": true
},
"electron-to-chromium": {
"version": "1.3.31",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.31.tgz",
"integrity": "sha512-XE4CLbswkZgZFn34cKFy1xaX+F5LHxeDLjY1+rsK9asDzknhbrd9g/n/01/acbU25KTsUSiLKwvlLyA+6XLUOA==",
"version": "1.3.32",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.32.tgz",
"integrity": "sha1-EdBoTAhA4APEvoko+KxfNdvCtOY=",
"dev": true
},
"elliptic": {
@ -5448,7 +5447,7 @@
"integrity": "sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI=",
"dev": true,
"requires": {
"postcss": "6.0.16"
"postcss": "6.0.17"
}
},
"idb-wrapper": {
@ -6116,7 +6115,7 @@
"integrity": "sha512-89ztIZ03aYK9f1uUrLXLsZndRge/JnZjzjpaN+lrse3coqz+8PR/dX4WLHpbF5fIKTXhDjFODOJw2328lPJ90g==",
"requires": {
"abab": "1.0.4",
"acorn": "5.3.0",
"acorn": "5.4.0",
"acorn-globals": "4.1.0",
"array-equal": "1.0.0",
"browser-process-hrtime": "0.1.2",
@ -8335,9 +8334,9 @@
"integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs="
},
"postcss": {
"version": "6.0.16",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.16.tgz",
"integrity": "sha512-m758RWPmSjFH/2MyyG3UOW1fgYbR9rtdzz5UNJnlm7OLtu4B2h9C6gi+bE4qFKghsBRFfZT8NzoQBs6JhLotoA==",
"version": "6.0.17",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.17.tgz",
"integrity": "sha512-Bl1nybsSzWYbP8O4gAVD8JIjZIul9hLNOPTGBIlVmZNUnNAGL+W0cpYWzVwfImZOwumct4c1SDvSbncVWKtXUw==",
"dev": true,
"requires": {
"chalk": "2.3.0",
@ -8748,7 +8747,7 @@
"integrity": "sha1-qWLi34LTvFptpqOGhBdHIE9B71s=",
"dev": true,
"requires": {
"postcss": "6.0.16",
"postcss": "6.0.17",
"postcss-value-parser": "3.3.0",
"read-cache": "1.0.0",
"resolve": "1.5.0"
@ -8793,7 +8792,7 @@
"dev": true,
"requires": {
"loader-utils": "1.1.0",
"postcss": "6.0.16",
"postcss": "6.0.17",
"postcss-load-config": "1.2.0",
"schema-utils": "0.3.0"
}
@ -8896,7 +8895,7 @@
"dev": true,
"requires": {
"caniuse-db": "1.0.30000800",
"electron-to-chromium": "1.3.31"
"electron-to-chromium": "1.3.32"
}
},
"has-flag": {
@ -9101,7 +9100,7 @@
"integrity": "sha1-ZhQOzs447wa/DT41XWm/WdFB6oU=",
"dev": true,
"requires": {
"postcss": "6.0.16"
"postcss": "6.0.17"
}
},
"postcss-modules-local-by-default": {
@ -9111,7 +9110,7 @@
"dev": true,
"requires": {
"css-selector-tokenizer": "0.7.0",
"postcss": "6.0.16"
"postcss": "6.0.17"
}
},
"postcss-modules-scope": {
@ -9121,7 +9120,7 @@
"dev": true,
"requires": {
"css-selector-tokenizer": "0.7.0",
"postcss": "6.0.16"
"postcss": "6.0.17"
}
},
"postcss-modules-values": {
@ -9131,7 +9130,7 @@
"dev": true,
"requires": {
"icss-replace-symbols": "1.1.0",
"postcss": "6.0.16"
"postcss": "6.0.17"
}
},
"postcss-normalize-charset": {
@ -9470,7 +9469,7 @@
"mime": "1.6.0",
"minimatch": "3.0.4",
"mkdirp": "0.5.1",
"postcss": "6.0.16",
"postcss": "6.0.17",
"xxhashjs": "0.2.2"
}
},
@ -10163,16 +10162,16 @@
}
},
"rollup": {
"version": "0.55.1",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-0.55.1.tgz",
"integrity": "sha512-lV8lBkpA1PXsshgu8zy51QrGPvWDIhZjcShEyMKk/Riobz4xwutSb0TjAtRyS6wtnn5LNVmCL7KIj4pirOhEdw=="
"version": "0.55.3",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-0.55.3.tgz",
"integrity": "sha512-2TgimJ7pk+XfPT0DmAcOqq9qdXlJ04qKyzyLm1WvPS/E6XdXEXyG5u6L8AsjxOaKoEBlYGliPzo99jxwhn2NYQ=="
},
"rollup-plugin-commonjs": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-8.3.0.tgz",
"integrity": "sha512-PYs3OiYgENFYEmI3vOEm5nrp3eY90YZqd5vGmQqeXmhJsAWFIrFdROCvOasqJ1HgeTvqyYo9IGXnFDyoboNcgQ==",
"requires": {
"acorn": "5.3.0",
"acorn": "5.4.0",
"estree-walker": "0.5.1",
"magic-string": "0.22.4",
"resolve": "1.5.0",
@ -10971,37 +10970,6 @@
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
},
"source-map-loader": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-0.2.3.tgz",
"integrity": "sha512-MYbFX9DYxmTQFfy2v8FC1XZwpwHKYxg3SK8Wb7VPBKuhDjz8gi9re2819MsG4p49HDyiOSUKlmZ+nQBArW5CGw==",
"dev": true,
"requires": {
"async": "2.6.0",
"loader-utils": "0.2.17",
"source-map": "0.6.1"
},
"dependencies": {
"loader-utils": {
"version": "0.2.17",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz",
"integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=",
"dev": true,
"requires": {
"big.js": "3.2.0",
"emojis-list": "2.1.0",
"json5": "0.5.1",
"object-assign": "4.1.1"
}
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
}
}
},
"source-map-resolve": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.1.tgz",
@ -11778,13 +11746,13 @@
"resolve": "1.5.0",
"semver": "5.5.0",
"tslib": "1.9.0",
"tsutils": "2.19.1"
"tsutils": "2.20.0"
}
},
"tsutils": {
"version": "2.19.1",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.19.1.tgz",
"integrity": "sha512-1B3z4H4HddgzWptqLzwrJloDEsyBt8DvZhnFO14k7A4RsQL/UhEfQjD4hpcY5NpF3veBkjJhQJ8Bl7Xp96cN+A==",
"version": "2.20.0",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.20.0.tgz",
"integrity": "sha512-qPOBy1/hwLdBxh/TNIpim5qL1WRMR0tgVGBB6shjnpw6/SuS5ZKYyXXxKDYsMsMtVdFOcL+XPGZVEuc+eCOo4A==",
"dev": true,
"requires": {
"tslib": "1.9.0"
@ -12465,7 +12433,7 @@
"integrity": "sha512-fxxKXoicjdXNUMY7LIdY89tkJJJ0m1Oo8PQutZ5rLgWbV5QVKI15Cn7+/IHnRTd3vfKfiwBx6SBqlorAuNA8LA==",
"dev": true,
"requires": {
"acorn": "5.3.0",
"acorn": "5.4.0",
"acorn-dynamic-import": "2.0.2",
"ajv": "5.5.2",
"ajv-keywords": "2.1.1",

View File

@ -16,6 +16,8 @@ const routes: Routes = [
{ path: 'no-routing-nav', loadChildren: 'app/no-routing-nav/no-routing-nav.module#NoRoutingNavModule' },
{ path: 'modal', loadChildren: 'app/modal/modal.module#ModalModule' },
{ path: 'popover', loadChildren: 'app/popover/popover.module#PopoverModule' },
{ path: 'virtual-scroll', loadChildren: 'app/virtual-scroll/virtual-scroll.module#VirtualScrollModule' },
];
@NgModule({

View File

@ -4,7 +4,7 @@ import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { IonicAngularModule, IonicRouterModule } from '@ionic/angular';
import { IonicAngularModule } from '@ionic/angular';
@NgModule({
declarations: [AppComponent],
@ -12,7 +12,6 @@ import { IonicAngularModule, IonicRouterModule } from '@ionic/angular';
AppRoutingModule,
BrowserModule,
IonicAngularModule.forRoot(),
IonicRouterModule.forRoot()
],
bootstrap: [AppComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA]

View File

@ -37,6 +37,9 @@
<li>
<a href='popover'>Popover Page</a>
</li>
<li>
<a href='virtual-scroll'>Virtual Scroll Page</a>
</li>
</ul>
</div>

View File

@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common';
import { NoRoutingNavPageComponent } from './no-routing-nav.component';
import { NoRoutingNavRoutingModule } from './no-routing-nav-routing.module';
import { IonicAngularModule, IonicRouterModule} from '@ionic/angular';
import { IonicAngularModule} from '@ionic/angular';
import { PageOne } from './pages/page-one';
import { PageTwo } from './pages/page-two';
@ -14,7 +14,6 @@ import { PageThree } from './pages/page-three';
CommonModule,
NoRoutingNavRoutingModule,
IonicAngularModule,
IonicRouterModule
],
declarations: [
NoRoutingNavPageComponent,

View File

@ -0,0 +1,29 @@
import { Component } from '@angular/core';
import { ToastController } from '@ionic/angular';
@Component({
selector: 'app-virtual-scroll-page',
template: `
<ion-app>
<ion-page>
<ion-header>
<ion-toolbar>
<ion-title>Test</ion-title>
</ion-toolbar>
</ion-header>
<ion-content padding>
<ion-virtual-scroll [items]="items">
<ion-item *virtualItem="let item">{{item}}</ion-item>
</ion-virtual-scroll>
</ion-content>
</ion-page>
</ion-app>`
})
export class VirtualScrollPageComponent {
items: string[];
constructor() {
this.items = Array.from({length: 1000}, (_, i) => i + '');
}
}

View File

@ -0,0 +1,14 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { VirtualScrollPageComponent } from './virtual-scroll-page.component';
const routes: Routes = [
{ path: '', component: VirtualScrollPageComponent }
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class VirtualScrollRoutingModule { }

View File

@ -0,0 +1,17 @@
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { CommonModule } from '@angular/common';
import { IonicAngularModule } from '@ionic/angular';
import { VirtualScrollPageComponent } from './virtual-scroll-page.component';
import { VirtualScrollRoutingModule } from './virtual-scroll-routing.module';
@NgModule({
imports: [
CommonModule,
IonicAngularModule,
VirtualScrollRoutingModule
],
declarations: [VirtualScrollPageComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class VirtualScrollModule { }