mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-18 19:21:34 +08:00
fix(virtual-scroll): JSX can render headers and footers
This commit is contained in:
@ -260,11 +260,6 @@ and what data to give to the header template. The function must return
|
||||
|
||||
|
||||
|
||||
#### itemRender
|
||||
|
||||
|
||||
|
||||
|
||||
#### items
|
||||
|
||||
|
||||
@ -275,12 +270,22 @@ entire virtual scroll is reset, which is an expensive operation and
|
||||
should be avoided if possible.
|
||||
|
||||
|
||||
#### nodeHeight
|
||||
#### nodeRender
|
||||
|
||||
|
||||
|
||||
|
||||
#### renderer
|
||||
#### renderFooter
|
||||
|
||||
|
||||
|
||||
|
||||
#### renderHeader
|
||||
|
||||
|
||||
|
||||
|
||||
#### renderItem
|
||||
|
||||
|
||||
|
||||
@ -364,11 +369,6 @@ and what data to give to the header template. The function must return
|
||||
|
||||
|
||||
|
||||
#### item-render
|
||||
|
||||
|
||||
|
||||
|
||||
#### items
|
||||
|
||||
|
||||
@ -379,12 +379,22 @@ entire virtual scroll is reset, which is an expensive operation and
|
||||
should be avoided if possible.
|
||||
|
||||
|
||||
#### node-height
|
||||
#### node-render
|
||||
|
||||
|
||||
|
||||
|
||||
#### renderer
|
||||
#### render-footer
|
||||
|
||||
|
||||
|
||||
|
||||
#### render-header
|
||||
|
||||
|
||||
|
||||
|
||||
#### render-item
|
||||
|
||||
|
||||
|
||||
|
@ -82,7 +82,7 @@
|
||||
return el;
|
||||
}
|
||||
|
||||
virtual.itemRender = (el, cell) => {
|
||||
virtual.nodeRender = (el, cell) => {
|
||||
if (cell.type === 0) return renderItem(el, cell.value);
|
||||
return renderHeader(el, cell.value);
|
||||
};
|
||||
|
@ -56,7 +56,7 @@
|
||||
return el;
|
||||
}
|
||||
|
||||
virtual.itemRender = (el, cell) => {
|
||||
virtual.nodeRender = (el, cell) => {
|
||||
if (cell.type === 0) return renderItem(el, cell.value);
|
||||
return renderHeader(el, cell.value);
|
||||
};
|
||||
|
@ -40,7 +40,6 @@ export interface VirtualNode {
|
||||
const MIN_READS = 2;
|
||||
|
||||
|
||||
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, cell: Cell, domIndex?: number) => HTMLElement;
|
||||
@ -104,7 +103,7 @@ export function updateVDom(dom: VirtualNode[], heightIndex: Uint32Array, cells:
|
||||
|
||||
export function doRender(
|
||||
el: HTMLElement,
|
||||
itemRender: ItemRenderFn,
|
||||
nodeRender: ItemRenderFn,
|
||||
dom: VirtualNode[],
|
||||
updateCellHeight: Function
|
||||
) {
|
||||
@ -119,9 +118,9 @@ export function doRender(
|
||||
if (node.change === NodeChange.Cell) {
|
||||
if (i < childrenNu) {
|
||||
child = children[i] as HTMLElement;
|
||||
itemRender(child, cell, i);
|
||||
nodeRender(child, cell, i);
|
||||
} else {
|
||||
child = itemRender(null, cell, i);
|
||||
child = nodeRender(null, cell, i);
|
||||
child.classList.add('virtual-item');
|
||||
el.appendChild(child);
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { Component, Element, EventListenerEnable, Listen, Method, Prop, Watch } from '@stencil/core';
|
||||
import { QueueController } from '../../interface';
|
||||
import { Cell, DomRenderFn, HeaderFn, ItemHeightFn,
|
||||
ItemRenderFn, NodeHeightFn, Range,
|
||||
ItemRenderFn, Range,
|
||||
VirtualNode, calcCells, calcHeightIndex, doRender,
|
||||
findCellIndex, getRange, getShouldUpdate, getViewport,
|
||||
inplaceUpdate, positionForIndex, resizeBuffer, updateVDom } from './virtual-scroll-utils';
|
||||
inplaceUpdate, positionForIndex, resizeBuffer, updateVDom, CellType } from './virtual-scroll-utils';
|
||||
|
||||
|
||||
@Component({
|
||||
@ -98,11 +98,15 @@ export class VirtualScroll {
|
||||
* should be avoided if possible.
|
||||
*/
|
||||
@Prop() items?: any[];
|
||||
|
||||
@Prop() renderer?: (item: any) => JSX.Element;
|
||||
@Prop() nodeHeight?: NodeHeightFn;
|
||||
@Prop() itemHeight?: ItemHeightFn;
|
||||
@Prop() itemRender?: ItemRenderFn;
|
||||
|
||||
// JSX API
|
||||
@Prop() renderItem?: (item: any, index: number) => JSX.Element;
|
||||
@Prop() renderHeader?: (item: any, index: number) => JSX.Element;
|
||||
@Prop() renderFooter?: (item: any, index: number) => JSX.Element;
|
||||
|
||||
// Low level API
|
||||
@Prop() nodeRender?: ItemRenderFn;
|
||||
@Prop() domRender?: DomRenderFn;
|
||||
|
||||
@Watch('itemHeight')
|
||||
@ -255,11 +259,11 @@ export class VirtualScroll {
|
||||
);
|
||||
|
||||
// write DOM
|
||||
if (this.itemRender) {
|
||||
doRender(this.el, this.itemRender, this.virtualDom, this.updateCellHeight.bind(this));
|
||||
if (this.nodeRender) {
|
||||
doRender(this.el, this.nodeRender, this.virtualDom, this.updateCellHeight.bind(this));
|
||||
} else if (this.domRender) {
|
||||
this.domRender(this.virtualDom);
|
||||
} else if (this.renderer) {
|
||||
} else if (this.renderItem) {
|
||||
this.el.forceUpdate();
|
||||
}
|
||||
if (this.heightChanged) {
|
||||
@ -370,24 +374,33 @@ export class VirtualScroll {
|
||||
}
|
||||
}
|
||||
|
||||
renderVirtualNode(node: VirtualNode) {
|
||||
const cell = node.cell;
|
||||
switch(cell.type) {
|
||||
case CellType.Item: return this.renderItem!(cell.value, cell.index);
|
||||
case CellType.Header: return this.renderHeader!(cell.value, cell.index);
|
||||
case CellType.Footer: return this.renderFooter!(cell.value, cell.index);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const renderer = this.renderer;
|
||||
if (renderer) {
|
||||
return this.virtualDom.map((dom) => {
|
||||
const item = renderer(dom.cell.value) as any;
|
||||
const renderItem = this.renderItem;
|
||||
if (renderItem) {
|
||||
return this.virtualDom.map((node) => {
|
||||
const item = this.renderVirtualNode(node) as any;
|
||||
const classes = ['virtual-item'];
|
||||
if (!item.vattrs) {
|
||||
item.vattrs = {};
|
||||
}
|
||||
item.vattrs.class += ' virtual-item';
|
||||
if (!dom.visible) {
|
||||
if (!node.visible) {
|
||||
classes.push('virtual-loading');
|
||||
}
|
||||
item.vattrs.class += ' ' + classes.join(' ');
|
||||
if (!item.vattrs.style) {
|
||||
item.vattrs.style = {};
|
||||
}
|
||||
item.vattrs.style['transform'] = `translate3d(0,${dom.top}px,0)`;
|
||||
item.vattrs.style['transform'] = `translate3d(0,${node.top}px,0)`;
|
||||
return item;
|
||||
});
|
||||
}
|
||||
|
Reference in New Issue
Block a user