Fix updates
Signed-off-by: RMidhunSuresh <rmidhunsuresh@gmail.com>
This commit is contained in:
parent
452eee6767
commit
f05574f579
1 changed files with 51 additions and 14 deletions
|
@ -42,6 +42,10 @@ class ItemRange {
|
||||||
totalSize() {
|
totalSize() {
|
||||||
return this.topCount + this.renderCount + this.bottomCount;
|
return this.topCount + this.renderCount + this.bottomCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
normalize(idx) {
|
||||||
|
return idx - this.topCount;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class LazyListView extends ListView {
|
export class LazyListView extends ListView {
|
||||||
|
@ -64,7 +68,7 @@ export class LazyListView extends ListView {
|
||||||
return new ItemRange(topCount, renderCount, bottomCount);
|
return new ItemRange(topCount, renderCount, bottomCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
_renderMoreIfNeeded() {
|
_renderIfNeeded() {
|
||||||
const range = this._getVisibleRange();
|
const range = this._getVisibleRange();
|
||||||
const intersectRange = range.expand(this._overflowMargin);
|
const intersectRange = range.expand(this._overflowMargin);
|
||||||
const renderRange = range.expand(this._overflowItems);
|
const renderRange = range.expand(this._overflowItems);
|
||||||
|
@ -83,6 +87,7 @@ export class LazyListView extends ListView {
|
||||||
}
|
}
|
||||||
|
|
||||||
_renderItems(items) {
|
_renderItems(items) {
|
||||||
|
this._childInstances = [];
|
||||||
const fragment = document.createDocumentFragment();
|
const fragment = document.createDocumentFragment();
|
||||||
for (const item of items) {
|
for (const item of items) {
|
||||||
const view = this._childCreator(item.value);
|
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.
|
But in most of these scroll events, we return early.
|
||||||
Do we need to do more (like event throttling)?
|
Do we need to do more (like event throttling)?
|
||||||
*/
|
*/
|
||||||
this._parent.addEventListener("scroll", () => this._renderMoreIfNeeded());
|
this._parent.addEventListener("scroll", () => this._renderIfNeeded());
|
||||||
this._renderMoreIfNeeded();
|
this._renderIfNeeded();
|
||||||
return this._parent;
|
return this._parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,49 +128,81 @@ export class LazyListView extends ListView {
|
||||||
if (!this._list) { return; }
|
if (!this._list) { return; }
|
||||||
this._subscription = this._list.subscribe(this);
|
this._subscription = this._list.subscribe(this);
|
||||||
this._childInstances = [];
|
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() {
|
onAdd() {
|
||||||
this._renderMoreIfNeeded();
|
this._renderIfNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
onRemove() {
|
onRemove() {
|
||||||
this._renderMoreIfNeeded();
|
this._renderIfNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
onUpdate(idx, value, params) {
|
onUpdate(idx, value, params) {
|
||||||
console.log("onUpdate");
|
|
||||||
if (this._renderRange.containsIndex(idx)) {
|
if (this._renderRange.containsIndex(idx)) {
|
||||||
super.onUpdate(idx, value, params);
|
const normalizedIdx = this._renderRange.normalize(idx);
|
||||||
|
super.onUpdate(normalizedIdx, value, params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
recreateItem(idx, value) {
|
recreateItem(idx, value) {
|
||||||
console.log("recreateItem");
|
|
||||||
if (this._renderRange.containsIndex(idx)) {
|
if (this._renderRange.containsIndex(idx)) {
|
||||||
super.recreateItem(idx, value)
|
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) {
|
onMove(fromIdx, toIdx, value) {
|
||||||
console.log("onMove");
|
|
||||||
const fromInRange = this._renderRange.containsIndex(fromIdx);
|
const fromInRange = this._renderRange.containsIndex(fromIdx);
|
||||||
const toInRange = this._renderRange.containsIndex(toIdx);
|
const toInRange = this._renderRange.containsIndex(toIdx);
|
||||||
|
const normalizedFromIdx = this._renderRange.normalize(fromIdx);
|
||||||
|
const normalizedToIdx = this._renderRange.normalize(toIdx);
|
||||||
if (fromInRange && toInRange) {
|
if (fromInRange && toInRange) {
|
||||||
super.onMove(fromIdx, toIdx, value);
|
super.onMove(normalizedFromIdx, normalizedToIdx, value);
|
||||||
}
|
}
|
||||||
else if (fromInRange && !toInRange) {
|
else if (fromInRange && !toInRange) {
|
||||||
this.onBeforeListChanged();
|
this.onBeforeListChanged();
|
||||||
const [child] = this._childInstances.splice(fromIdx, 1);
|
const [child] = this._childInstances.splice(normalizedFromIdx, 1);
|
||||||
child.root().remove();
|
child.root().remove();
|
||||||
|
this._renderAdditionalElement(fromIdx, toIdx);
|
||||||
this.onListChanged();
|
this.onListChanged();
|
||||||
}
|
}
|
||||||
else if (!fromInRange && toInRange) {
|
else if (!fromInRange && toInRange) {
|
||||||
this.onBeforeListChanged();
|
this.onBeforeListChanged();
|
||||||
const child = this._childCreator(value);
|
const child = this._childCreator(value);
|
||||||
this._childInstances.splice(toIdx, 0, child);
|
this._childInstances.splice(normalizedToIdx, 0, child);
|
||||||
insertAt(this._root, toIdx, mountView(child, this._mountArgs));
|
this._removeAdditionalElement(fromIdx, toIdx);
|
||||||
|
insertAt(this._root, normalizedToIdx, mountView(child, this._mountArgs));
|
||||||
this.onListChanged();
|
this.onListChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue