Skip to content

fix(vtable): map sorted view index to source record in deleteRecords/updateRecords - #5330

Open
william-xue wants to merge 1 commit into
VisActor:developfrom
william-xue:fix/sorted-sync-record-index
Open

william-xue wants to merge 1 commit into
VisActor:developfrom
william-xue:fix/sorted-sync-record-index

Conversation

@william-xue

Copy link
Copy Markdown

[中文版模板 / Chinese template]

🤔 This is a ...

  • New feature
  • Bug fix
  • TypeScript definition update
  • Bundle size optimization
  • Performance optimization
  • Enhancement feature
  • Refactoring
  • Update dependency
  • Code style optimization
  • Test Case
  • Branch merge
  • Site / documentation update
  • Demo update
  • Workflow
  • Chore
  • Release
  • Other (about what?)

🔗 Related issue link

No tracking issue. Found while checking syncRecordOperationsToSourceRecords on a sorted table.

💡 Background and solution

syncRecordOperationsToSourceRecords: true promises that deleteRecords / updateRecords write back to the array passed in options.records. Both APIs receive body display indices, and the sync branches in DataSource used that display index directly as an index into this.records:

// deleteRecords(recordIndexs, true)
const deletedRecord = this.records[viewIndex];   // viewIndex is a display index

// updateRecords(records, recordIndexs, true)
const oldRecord = this.records[recordIndex];     // recordIndex is a display index

this.records is _source, i.e. the data source array in source order. Sorting does not reorder _source: DataSource.sort() only stores the view → source mapping in currentIndexedData, which is exactly what the non-sync paths already use (deleteRecordsForSorted / updateRecordsForSorted both read this.currentIndexedData[recordIndex]). Filtering keeps the same contract, because the view index then maps identically onto the filtered _source.

So on a sorted table the sync path touched the wrong record. Reproduced with the published 1.26.8 UMD bundle (desc-sorted id, 5 records, headless Chrome):

operation (view [5,4,3,2,1]) before after
deleteRecords([0]) source [2,3,4,5], view [5,4,3,2] — id 5 still visible, id 1 silently dropped source [1,2,3,4], view [4,3,2,1]
updateRecords([{id:5,name:'FIVE-UPDATED'}], [0]) source [0] (id 1) replaced, view [5,5,4,3,2] — duplicate id 5 source id 5 replaced, view [5,4,3,2,1]

Fix: map the display index back to the data source index through currentIndexedData before reading this.records (_getRecordIndexFromViewIndex, identity when the table is neither sorted nor filtered, so the existing behavior is unchanged). Tree / grouped data are untouched — those entries are arrays and keep the previous fallback.

📝 Changelog

Language Changelog
🇺🇸 English fix(vtable): map sorted view index to the source record in deleteRecords/updateRecords
🇨🇳 Chinese 修复(vtable):排序状态下 deleteRecords/updateRecords 同步数据源时按视图索引映射到正确记录

☑️ Self-Check before Merge

⚠️ Please check all items below before requesting a reviewing. ⚠️

  • Doc is updated/provided or not needed
  • Demo is updated/provided or not needed
  • TypeScript definition is updated/provided or not needed
  • Changelog is provided or not needed

🚀 Summary

copilot:summary

🔍 Walkthrough

copilot:walkthrough

…updateRecords

deleteRecords/updateRecords receive body display indices, but the sync
branches of DataSource used them directly as indices into this.records
(_source, source order). Sorting keeps _source in source order and stores
the view -> source mapping in currentIndexedData, so on a sorted table the
wrong record was deleted/updated in the user's records array.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant