import QtQuick // Snapshot rows must have unique, stable ids. Delegates consume the rowData role. // Move and update surviving rows rather than resetting their interactive delegates. ListModel { id: root property var rows: [] dynamicRoles: true onRowsChanged: sync(rows) Component.onCompleted: sync(rows) function sync(snapshot) { for (let i = 0; i < snapshot.length; i++) { const row = snapshot[i]; const key = String(row.id); const snapshotText = JSON.stringify(row); let found = i; while (found < count && get(found).stableId !== key) found++; if (found === count) { insert(i, { stableId: key, rowData: row, snapshotText: snapshotText }); } else { if (found !== i) move(found, i, 1); if (get(i).snapshotText !== snapshotText) set(i, { stableId: key, rowData: row, snapshotText: snapshotText }); } } if (count > snapshot.length) remove(snapshot.length, count - snapshot.length); } }