Skip to content

Commit 319cc59

Browse files
committed
fix(virtual-repeat): make initially hidden elements display correctly
fixes: #73 Previous behavior was that any `virtual-repeat` that was initially hidden could not correctly calculate heights. New behavior is such that initially hidden elements can display correctly after they have been shown.
1 parent 91f944c commit 319cc59

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

src/virtual-repeat.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,9 @@ export class VirtualRepeat extends AbstractRepeater {
143143
}
144144
this._unsubscribeCollection();
145145
clearInterval(this.calcDistanceToTopInterval);
146+
if (this._sizeInterval) {
147+
clearInterval(this._sizeInterval);
148+
}
146149
}
147150

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

405-
_calcInitialHeights(itemsLength: number) {
408+
_calcInitialHeights(itemsLength: number): void {
406409
if (this._viewsLength > 0 && this._itemsLength === itemsLength || itemsLength <= 0) {
407410
return;
408411
}
@@ -411,7 +414,14 @@ export class VirtualRepeat extends AbstractRepeater {
411414
let firstViewElement = this.view(0).lastChild;
412415
this.itemHeight = calcOuterHeight(firstViewElement);
413416
if (this.itemHeight <= 0) {
414-
throw new Error('Could not calculate item height');
417+
this._sizeInterval = setInterval(()=>{
418+
let newCalcSize = calcOuterHeight(firstViewElement);
419+
if (newCalcSize > 0) {
420+
clearInterval(this._sizeInterval);
421+
this.itemsChanged();
422+
}
423+
}, 500);
424+
return;
415425
}
416426
this.scrollContainerHeight = this._fixedHeightContainer ? this._calcScrollHeight(this.scrollContainer) : document.documentElement.clientHeight;
417427
this.elementsInView = Math.ceil(this.scrollContainerHeight / this.itemHeight) + 1;
@@ -426,6 +436,7 @@ export class VirtualRepeat extends AbstractRepeater {
426436
// TODO This will cause scrolling back to top when swapping collection instances that have different lengths - instead should keep the scroll position
427437
this.scrollContainer.scrollTop = 0;
428438
this._first = 0;
439+
return;
429440
}
430441

431442
_calcScrollHeight(element: Element): number {

test/virtual-repeat-integration.spec.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,11 @@ describe('VirtualRepeat Integration', () => {
183183
let create;
184184
let items;
185185

186+
let hiddenComponent;
187+
let hiddenCreate;
188+
let hiddenVirtualRepeat;
189+
let hiddenViewModel;
190+
186191
beforeEach(() => {
187192
items = [];
188193
for(let i = 0; i < 1000; ++i) {
@@ -197,10 +202,23 @@ describe('VirtualRepeat Integration', () => {
197202
virtualRepeat = component.sut;
198203
viewModel = component.viewModel;
199204
});
205+
206+
hiddenComponent = StageComponent
207+
.withResources('src/virtual-repeat')
208+
.inView(`<div id="scrollContainer" style="height: 500px; overflow-y: scroll; display: none">
209+
<div style="height: ${itemHeight}px;" virtual-repeat.for="item of items">\${item}</div>
210+
</div>`)
211+
.boundTo({ items: items });
212+
213+
hiddenCreate = hiddenComponent.create().then(() => {
214+
hiddenVirtualRepeat = hiddenComponent.sut;
215+
hiddenViewModel = hiddenComponent.viewModel;
216+
});
200217
});
201218

202219
afterEach(() => {
203220
component.cleanUp();
221+
hiddenComponent.cleanUp();
204222
});
205223

206224
describe('handles delete', () => {
@@ -296,6 +314,18 @@ describe('VirtualRepeat Integration', () => {
296314
it('handles splice', done => {
297315
create.then(() => validateSplice(virtualRepeat, viewModel, done));
298316
});
317+
318+
it('handles displaying when initially hidden', done => {
319+
hiddenCreate.then(() => {
320+
hiddenVirtualRepeat.scrollContainer.style.display = "block";
321+
window.requestAnimationFrame(()=>{
322+
window.setTimeout(()=>{
323+
validateState(hiddenVirtualRepeat, hiddenViewModel);
324+
done();
325+
}, 750)
326+
});
327+
});
328+
});
299329
});
300330

301331
describe('iterating table', () => {

0 commit comments

Comments
 (0)