Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions src/virtual-repeat.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ export class VirtualRepeat extends AbstractRepeater {
}
this._unsubscribeCollection();
clearInterval(this.calcDistanceToTopInterval);
if (this._sizeInterval) {
clearInterval(this._sizeInterval);
}
}

itemsChanged(): void {
Expand Down Expand Up @@ -402,7 +405,7 @@ export class VirtualRepeat extends AbstractRepeater {
return this.view(0) ? this.view(0).overrideContext.$index : -1;
}

_calcInitialHeights(itemsLength: number) {
_calcInitialHeights(itemsLength: number): void {
if (this._viewsLength > 0 && this._itemsLength === itemsLength || itemsLength <= 0) {
return;
}
Expand All @@ -411,7 +414,14 @@ export class VirtualRepeat extends AbstractRepeater {
let firstViewElement = this.view(0).lastChild;
this.itemHeight = calcOuterHeight(firstViewElement);
if (this.itemHeight <= 0) {
throw new Error('Could not calculate item height');
this._sizeInterval = setInterval(()=>{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this._sizeInterval might need to be terminated in the detached callback as well. In case the item height never gets greater than 0.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ohh, good call. Do you think 500ms is fine for the interval? I just made it match the interval (time wise) with the one defined earlier in regards to scrolling. Possibly make it faster, slower?

let newCalcSize = calcOuterHeight(firstViewElement);
if (newCalcSize > 0) {
clearInterval(this._sizeInterval);
this.itemsChanged();
}
}, 500);
return;
}
this.scrollContainerHeight = this._fixedHeightContainer ? this._calcScrollHeight(this.scrollContainer) : document.documentElement.clientHeight;
this.elementsInView = Math.ceil(this.scrollContainerHeight / this.itemHeight) + 1;
Expand All @@ -426,6 +436,7 @@ export class VirtualRepeat extends AbstractRepeater {
// TODO This will cause scrolling back to top when swapping collection instances that have different lengths - instead should keep the scroll position
this.scrollContainer.scrollTop = 0;
this._first = 0;
return;
}

_calcScrollHeight(element: Element): number {
Expand Down
30 changes: 30 additions & 0 deletions test/virtual-repeat-integration.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,11 @@ describe('VirtualRepeat Integration', () => {
let create;
let items;

let hiddenComponent;
let hiddenCreate;
let hiddenVirtualRepeat;
let hiddenViewModel;

beforeEach(() => {
items = [];
for(let i = 0; i < 1000; ++i) {
Expand All @@ -197,10 +202,23 @@ describe('VirtualRepeat Integration', () => {
virtualRepeat = component.sut;
viewModel = component.viewModel;
});

hiddenComponent = StageComponent
.withResources('src/virtual-repeat')
.inView(`<div id="scrollContainer" style="height: 500px; overflow-y: scroll; display: none">
<div style="height: ${itemHeight}px;" virtual-repeat.for="item of items">\${item}</div>
</div>`)
.boundTo({ items: items });

hiddenCreate = hiddenComponent.create().then(() => {
hiddenVirtualRepeat = hiddenComponent.sut;
hiddenViewModel = hiddenComponent.viewModel;
});
});

afterEach(() => {
component.cleanUp();
hiddenComponent.cleanUp();
});

describe('handles delete', () => {
Expand Down Expand Up @@ -296,6 +314,18 @@ describe('VirtualRepeat Integration', () => {
it('handles splice', done => {
create.then(() => validateSplice(virtualRepeat, viewModel, done));
});

it('handles displaying when initially hidden', done => {
hiddenCreate.then(() => {
hiddenVirtualRepeat.scrollContainer.style.display = "block";
window.requestAnimationFrame(()=>{
window.setTimeout(()=>{
validateState(hiddenVirtualRepeat, hiddenViewModel);
done();
}, 750)
});
});
});
});

describe('iterating table', () => {
Expand Down