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,