Fix updates

Signed-off-by: RMidhunSuresh <rmidhunsuresh@gmail.com>
This commit is contained in:
RMidhunSuresh 2021-07-12 13:57:37 +05:30
parent 452eee6767
commit f05574f579

View File

@ -42,6 +42,10 @@ class ItemRange {
totalSize() {
return this.topCount + this.renderCount + this.bottomCount;
}
normalize(idx) {
return idx - this.topCount;
}
}
export class LazyListView extends ListView {
@ -64,7 +68,7 @@ export class LazyListView extends ListView {
return new ItemRange(topCount, renderCount, bottomCount);
}
_renderMoreIfNeeded() {
_renderIfNeeded() {
const range = this._getVisibleRange();
const intersectRange = range.expand(this._overflowMargin);
const renderRange = range.expand(this._overflowItems);
@ -83,6 +87,7 @@ export class LazyListView extends ListView {
}
_renderItems(items) {
this._childInstances = [];
const fragment = document.createDocumentFragment();
for (const item of items) {
const view = this._childCreator(item.value);
@ -114,8 +119,8 @@ export class LazyListView extends ListView {
But in most of these scroll events, we return early.
Do we need to do more (like event throttling)?
*/
this._parent.addEventListener("scroll", () => this._renderMoreIfNeeded());
this._renderMoreIfNeeded();
this._parent.addEventListener("scroll", () => this._renderIfNeeded());
this._renderIfNeeded();
return this._parent;
}
@ -123,49 +128,81 @@ export class LazyListView extends ListView {
if (!this._list) { return; }
this._subscription = this._list.subscribe(this);
this._childInstances = [];
// todo: this breaks update in parent
}
// onAdd, onRemove, ... should be called only if the element is already rendered
// If size of the list changes, re-render
onAdd() {
this._renderMoreIfNeeded();
this._renderIfNeeded();
}
onRemove() {
this._renderMoreIfNeeded();
this._renderIfNeeded();
}
onUpdate(idx, value, params) {
console.log("onUpdate");
if (this._renderRange.containsIndex(idx)) {
super.onUpdate(idx, value, params);
const normalizedIdx = this._renderRange.normalize(idx);
super.onUpdate(normalizedIdx, value, params);
}
}
recreateItem(idx, value) {
console.log("recreateItem");
if (this._renderRange.containsIndex(idx)) {
super.recreateItem(idx, value)
}
}
_renderAdditionalElement(fromIdx, toIdx) {
const {topCount, renderCount} = this._renderRange;
const childFromIndex = index => this._childCreator(this._list.get(index));
if (toIdx < fromIdx) {
// Element is moved up the list, so render element from top boundary
const index = topCount;
const child = childFromIndex(index);
// Modify childInstances here
this._root.insertBefore(mountView(child, this._mountArgs), this._root.firstChild);
}
else {
// Element is moved down the list, so render element from bottom boundary
const index = topCount + renderCount - 1;
const child = childFromIndex(index);
this._root.appendChild(mountView(child, this._mountArgs));
}
}
_removeAdditionalElement(fromIdx, toIdx) {
if (toIdx < fromIdx) {
// Element comes from the bottom, so remove element at bottom
this._root.lastChild.remove();
}
else {
this._root.firstChild.remove();
}
}
onMove(fromIdx, toIdx, value) {
console.log("onMove");
const fromInRange = this._renderRange.containsIndex(fromIdx);
const toInRange = this._renderRange.containsIndex(toIdx);
const normalizedFromIdx = this._renderRange.normalize(fromIdx);
const normalizedToIdx = this._renderRange.normalize(toIdx);
if (fromInRange && toInRange) {
super.onMove(fromIdx, toIdx, value);
super.onMove(normalizedFromIdx, normalizedToIdx, value);
}
else if (fromInRange && !toInRange) {
this.onBeforeListChanged();
const [child] = this._childInstances.splice(fromIdx, 1);
const [child] = this._childInstances.splice(normalizedFromIdx, 1);
child.root().remove();
this._renderAdditionalElement(fromIdx, toIdx);
this.onListChanged();
}
else if (!fromInRange && toInRange) {
this.onBeforeListChanged();
const child = this._childCreator(value);
this._childInstances.splice(toIdx, 0, child);
insertAt(this._root, toIdx, mountView(child, this._mountArgs));
this._childInstances.splice(normalizedToIdx, 0, child);
this._removeAdditionalElement(fromIdx, toIdx);
insertAt(this._root, normalizedToIdx, mountView(child, this._mountArgs));
this.onListChanged();
}
}