Skip to content

Commit

Permalink
fix(cdk:scroll): virtual list render error after dataSource change (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
sallerli1 committed Jul 4, 2024
1 parent d39c7e8 commit 491d5aa
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 7 deletions.
20 changes: 19 additions & 1 deletion packages/cdk/scroll/src/virtual/composables/useRenderPool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,14 @@ export function useRenderPool(
updatePoolItem(poolItem, item, index, itemKey)
})

const recycledItems: PoolItem[] = []

// remove deleted items
for (const inactiveKey of inactiveKeys) {
const index = items.findIndex(item => item.key === inactiveKey)

if (index > -1) {
recycledItems.push(items[index])
items.splice(index, 1)
}
}
Expand All @@ -156,6 +159,11 @@ export function useRenderPool(
if (updated) {
items.sort((item1, item2) => item1.index - item2.index)
}

return {
items,
recycledItems,
}
}

const updateColPool = (rowPoolItem: RowPoolItem, left: number, right: number, recycleAll: boolean) => {
Expand Down Expand Up @@ -200,7 +208,17 @@ export function useRenderPool(
}

const updateRowPool = (top: number, bottom: number, recycleAll: boolean) => {
updatePool(renderedItems.value, rowPool, props.dataSource, top, bottom, recycleAll)
const { recycledItems } = updatePool(renderedItems.value, rowPool, props.dataSource, top, bottom, recycleAll)

;(recycledItems as RowPoolItem[]).forEach(item => {
const pool = colPools[item.key]

if (pool) {
item.cols?.forEach(col => pool.recyclePoolItem(col))
}

item.cols = []
})

if (!props.rowModifier) {
return
Expand Down
16 changes: 10 additions & 6 deletions packages/cdk/scroll/src/virtual/composables/useScrollState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,17 @@ export function useScrollState(
],
(
[enabled, dataSource, bufferSize, rowHeight, colWidth, height, width, getKey, scroll],
[, , , , , oldHeight, oldWidth],
[, oldDataSource, , , , oldHeight, oldWidth],
) => {
// to ensure that the rendered size is stable between render cycles
// the rendered size should be at least the size of that in last render tick
// we do this to maximize render pool reusage
let minHorizontalLength: number[] | undefined
let minVerticalLength: number | undefined
if (oldDataSource !== dataSource || oldDataSource.length !== dataSource.length) {
calculated = false
}

if (oldWidth === width) {
minHorizontalLength = rightIndex.value.map((_rightIndex, index) => _rightIndex - leftIndex.value[index])
}
Expand Down Expand Up @@ -155,7 +159,7 @@ export function useScrollState(
calculated = true
}
},
{ immediate: true },
{ immediate: true, flush: 'pre' },
)

return { scrollHeight, scrollWidth, scrollOffsetTop, scrollOffsetLeft, topIndex, bottomIndex, leftIndex, rightIndex }
Expand Down Expand Up @@ -213,7 +217,7 @@ function calcVerticalState(
let _renderedHeight = 0

for (let index = 0; index < dataLength; index += 1) {
const rowHeight = getRowHeight(index)
const rowHeight = getRowHeight(getKey(rows[index]))
const currentItemBottom = scrollHeight + rowHeight

if (currentItemBottom >= scrollTop && topIndex === undefined) {
Expand Down Expand Up @@ -246,14 +250,14 @@ function calcVerticalState(
for (let index = 0; index < bufferSize; index += 1) {
if (topIndex !== 0) {
topIndex -= 1
const appendedRowHeight = getRowHeight(topIndex)
const appendedRowHeight = getRowHeight(getKey(rows[topIndex]))
offsetTop! -= appendedRowHeight
_renderedHeight += appendedRowHeight
}

if (bottomIndex !== dataLength - 1) {
bottomIndex += 1
_renderedHeight += getRowHeight(bottomIndex)
_renderedHeight += getRowHeight(getKey(rows[bottomIndex]))
}
}

Expand All @@ -265,7 +269,7 @@ function calcVerticalState(
) {
if (bottomIndex !== dataLength - 1) {
bottomIndex += 1
_renderedHeight += getRowHeight(bottomIndex)
_renderedHeight += getRowHeight(getKey(rows[bottomIndex]))
}
}

Expand Down

0 comments on commit 491d5aa

Please sign in to comment.