diff --git a/src/array-virtual-repeat-strategy.js b/src/array-virtual-repeat-strategy.js index a961cc4..cd8cab6 100644 --- a/src/array-virtual-repeat-strategy.js +++ b/src/array-virtual-repeat-strategy.js @@ -1,5 +1,5 @@ import {ArrayRepeatStrategy} from 'aurelia-templating-resources/array-repeat-strategy'; -import {createFullOverrideContext, updateOverrideContexts, refreshBinding} from 'aurelia-templating-resources/repeat-utilities'; +import {createFullOverrideContext, updateOverrideContexts, updateOverrideContext, refreshBinding} from 'aurelia-templating-resources/repeat-utilities'; /** * A strategy for repeating a template over an array. @@ -42,6 +42,7 @@ export class ArrayVirtualRepeatStrategy extends ArrayRepeatStrategy { _inPlaceProcessItems(repeat, items) { let itemsLength = items.length; let viewsLength = repeat.viewSlot.children.length; + let first = repeat.first; // remove unneeded views. while (viewsLength > repeat.numberOfDomElements) { viewsLength--; @@ -55,14 +56,14 @@ export class ArrayVirtualRepeatStrategy extends ArrayRepeatStrategy { let last = i === itemsLength - 1; let middle = i !== 0 && !last; // any changes to the binding context? - if (view.bindingContext[local] === items[i] + if (view.bindingContext[local] === items[i + first] && view.overrideContext.$middle === middle && view.overrideContext.$last === last) { // no changes. continue... continue; } // update the binding context and refresh the bindings. - view.bindingContext[local] = items[i]; + view.bindingContext[local] = items[i + first]; view.overrideContext.$middle = middle; view.overrideContext.$last = last; let j = view.bindings.length; @@ -100,8 +101,7 @@ export class ArrayVirtualRepeatStrategy extends ArrayRepeatStrategy { this._standardProcessInstanceMutated(repeat, array, splices); return; } - repeat._updateViews(repeat.items, splices); - //this._inPlaceProcessItems(repeat, array); + this._updateViews(repeat, repeat.items, splices); } _standardProcessInstanceMutated(repeat, array, splices) { @@ -137,12 +137,12 @@ export class ArrayVirtualRepeatStrategy extends ArrayRepeatStrategy { if (rmPromises.length > 0) { Promise.all(rmPromises).then(() => { this._handleAddedSplices(array, splices); - repeat._updateViews(array, splices); + repeat._updateViews(repeat, array, splices); repeat._updateSizes(); }); } else { this._handleAddedSplices(array, splices); - repeat._updateViews(array, splices); + this._updateViews(repeat, array, splices); repeat._updateSizes(); } } diff --git a/src/utilities.js b/src/utilities.js index 12fb3ee..f2d2d74 100644 --- a/src/utilities.js +++ b/src/utilities.js @@ -22,10 +22,18 @@ function getStyleValue(element, style){ } export function moveViewFirst(view, scrollView) { + // TODO Better support for table + if(scrollView.localName === 'table') { + scrollView = scrollView.firstElementChild; + } insertBeforeNode(view, scrollView, scrollView.childNodes[1]); } export function moveViewLast(view, scrollView, numberOfDomElements) { + // TODO Better support for table + if(scrollView.localName === 'table') { + scrollView = scrollView.firstElementChild; + } insertBeforeNode(view, scrollView, scrollView.children[numberOfDomElements]); } diff --git a/src/virtual-repeat.js b/src/virtual-repeat.js index 02301f1..c44558f 100644 --- a/src/virtual-repeat.js +++ b/src/virtual-repeat.js @@ -62,7 +62,13 @@ export class VirtualRepeat { attached(){ this.isAttached = true; - this.virtualScrollInner = this.element.parentNode; + + if (this.element.parentNode.localName === 'tbody') { + this.virtualScrollInner = this.element.parentNode.parentNode; + } else { + this.virtualScrollInner = this.element.parentNode; + } + this.virtualScroll = this.virtualScrollInner.parentElement; this.virtualScroll.style.overflow = 'hidden'; this.virtualScroll.tabIndex = '-1'; @@ -76,6 +82,7 @@ export class VirtualRepeat { }); this.itemsChanged(); + this.scroll(); } bind(bindingContext, overrideContext){ @@ -131,9 +138,6 @@ export class VirtualRepeat { this.strategy.instanceChanged(this, items, this.numberOfDomElements); this._calcScrollViewHeight(); this._calcIndicatorHeight(); - - // TODO Call this on scrolling - this.scroll(); } unbind(){ @@ -176,6 +180,11 @@ export class VirtualRepeat { ease = this.useEase ? 0.1 : 1, element, viewStart, viewEnd, marginTop, translateStyle, view, first; + // TODO Better solution for table support - strategy? + if (scrollView.localName === 'table') { + childNodes = scrollView.childNodes.firstElementChild; + } + this.currentY += (this.targetY - this.currentY) * ease; this.currentY = Math.round(this.currentY); @@ -188,6 +197,11 @@ export class VirtualRepeat { first = this.first = Math.ceil(this.currentY / itemHeight) * -1; if(first > this.previousFirst && first + numberOfDomElements - 1 <= items.length){ + if((first - this.previousFirst) > 1){ + first = this.first = this.previousFirst + 1; + this.currentY = this.currentY + itemHeight; + } + this.previousFirst = first; view = viewSlot.children[0]; @@ -199,7 +213,12 @@ export class VirtualRepeat { marginTop = itemHeight * first + "px"; scrollView.style.marginTop = marginTop; - }else if (first < this.previousFirst && !Object.is(first, -0)){ + }else if (first < this.previousFirst){ + if((this.previousFirst - first) > 1){ + first = this.first = this.previousFirst - 1; + this.currentY = this.currentY - itemHeight; + } + this.previousFirst = first; view = viewSlot.children[numberOfDomElements - 1]; @@ -227,16 +246,16 @@ export class VirtualRepeat { } scrollIndicator(){ - if(!this.indicator) { + if (!this.indicator) { return; } var scrolledPercentage, indicatorTranslateStyle; - scrolledPercentage = (-this.currentY) / ((this.items.length * this.itemHeight) - this.virtualScrollHeight); + scrolledPercentage = -this.currentY / (this.items.length * this.itemHeight - this.virtualScrollHeight); this.indicatorY = (this.virtualScrollHeight - this.indicatorHeight) * scrolledPercentage; - indicatorTranslateStyle = "translate3d(0px," + this.indicatorY + "px,0px)"; + indicatorTranslateStyle = "translate3d(0px," + this.indicatorY + "px,0px)"; this.indicator.style.webkitTransform = indicatorTranslateStyle; this.indicator.style.msTransform = indicatorTranslateStyle; this.indicator.style.transform = indicatorTranslateStyle; @@ -305,9 +324,19 @@ export class VirtualRepeat { } _createScrollIndicator(){ + if(this.indicator) { + return; + } var indicator; indicator = this.indicator = document.createElement('div'); - this.virtualScroll.appendChild(this.indicator); + + // TODO Better table support - maybe strategy? + if (this.virtualScroll.localName === 'table') { + this.virtualScroll.firstElementChild.appendChild(this.indicator); + } else { + this.virtualScroll.appendChild(this.indicator); + } + indicator.classList.add('au-scroll-indicator'); indicator.style.backgroundColor = '#cccccc'; indicator.style.top = '0px'; @@ -325,6 +354,9 @@ export class VirtualRepeat { } _calcInitialHeights() { + if (this.numberOfDomElements > 0) { + return; + } let listItems = this.virtualScrollInner.children; this.itemHeight = calcOuterHeight(listItems[0]); this.virtualScrollHeight = calcScrollHeight(this.virtualScroll);