fix(virtual-scroll): use correct item top calculation with header or footer function (#15948) (#17345)

- use the right index in updateVDom to update the top transition ()
- extend unit test to verify the top is also calculated right with a given headerFn and footerFn
- update the visibility of the node also if a given approxHeaderHeight/approxFooterHeight matches the calculated height

fixes #15948 fixes #17298
This commit is contained in:
David Boho
2019-03-26 21:17:03 +01:00
committed by Brandy Carney
parent 016fa16d44
commit a8a48a4ca4
3 changed files with 14 additions and 9 deletions

View File

@ -368,15 +368,20 @@ describe('updateVDom', () => {
it('should initialize empty VDOM', () => { it('should initialize empty VDOM', () => {
const vdom: VirtualNode[] = []; const vdom: VirtualNode[] = [];
const items = [1, 2, 3, 4, 5]; const items = [1, 2, 3, 4, 5];
const { heightIndex, cells } = mockVirtualScroll(items, () => 20); const { heightIndex, cells } = mockVirtualScroll(items, () => 20,
const range: Range = { offset: 1, length: 4 }; (_, i) => i === 1 ? 'hola' : null,
(_, i) => i === 2 ? 'hola' : null
);
const range: Range = { offset: 1, length: 6 };
updateVDom(vdom, heightIndex, cells, range); updateVDom(vdom, heightIndex, cells, range);
expect(vdom).toEqual([ expect(vdom).toEqual([
{ cell: cells[1], change: 2, d: false, top: 20, visible: true }, { cell: cells[1], change: 2, d: false, top: 20, visible: true },
{ cell: cells[2], change: 2, d: false, top: 40, visible: true }, { cell: cells[2], change: 2, d: false, top: 30, visible: true },
{ cell: cells[3], change: 2, d: false, top: 60, visible: true }, { cell: cells[3], change: 2, d: false, top: 50, visible: true },
{ cell: cells[4], change: 2, d: false, top: 80, visible: true } { cell: cells[4], change: 2, d: false, top: 70, visible: true },
{ cell: cells[5], change: 2, d: false, top: 80, visible: true },
{ cell: cells[6], change: 2, d: false, top: 100, visible: true }
]); ]);
}); });

View File

@ -46,7 +46,7 @@ export function updateVDom(dom: VirtualNode[], heightIndex: Uint32Array, cells:
for (const cell of toMutate) { for (const cell of toMutate) {
const node = pool.find(n => n.d && n.cell.type === cell.type); const node = pool.find(n => n.d && n.cell.type === cell.type);
const index = cell.index; const index = cell.i;
if (node) { if (node) {
node.d = false; node.d = false;
node.change = NODE_CHANGE_CELL; node.change = NODE_CHANGE_CELL;

View File

@ -327,9 +327,9 @@ export class VirtualScroll implements ComponentInterface {
if (cell !== this.cells[index]) { if (cell !== this.cells[index]) {
return; return;
} }
if (cell.height !== height || cell.visible !== true) {
console.debug(`[virtual] cell height or visibility changed ${cell.height}px -> ${height}px`);
cell.visible = true; cell.visible = true;
if (cell.height !== height) {
console.debug(`[virtual] cell height changed ${cell.height}px -> ${height}px`);
cell.height = height; cell.height = height;
this.indexDirty = Math.min(this.indexDirty, index); this.indexDirty = Math.min(this.indexDirty, index);
this.scheduleUpdate(); this.scheduleUpdate();