Skip to content

Commit 4b39126

Browse files
fix(for-of): correct content sizesCache recalculation
1 parent e501504 commit 4b39126

File tree

3 files changed

+48
-30
lines changed

3 files changed

+48
-30
lines changed

projects/igniteui-angular/src/lib/directives/for-of/for_of.directive.ts

Lines changed: 42 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -803,52 +803,69 @@ export class IgxForOfDirective<T, U extends T[] = T[]> extends IgxForOfToken<T,U
803803
* Function that recalculates and updates cache sizes.
804804
*/
805805
public recalcUpdateSizes() {
806-
const dimension = this.igxForScrollOrientation === 'horizontal' ? this.igxForSizePropName : 'height';
806+
const dimension = this.igxForScrollOrientation === 'horizontal' ?
807+
this.igxForSizePropName : 'height';
807808
const diffs = [];
808809
let totalDiff = 0;
809810
const l = this._embeddedViews.length;
810-
811811
const rNodes = this._embeddedViews.map(view =>
812812
view.rootNodes.find(node => node.nodeType === Node.ELEMENT_NODE) || view.rootNodes[0].nextElementSibling);
813-
814813
for (let i = 0; i < l; i++) {
815814
const rNode = rNodes[i];
816815
if (rNode) {
817816
const height = window.getComputedStyle(rNode).getPropertyValue('height');
818-
const h = parseFloat(height);
817+
const h = parseFloat(height) || parseInt(this.igxForItemSize, 10);
819818
const index = this.state.startIndex + i;
820-
821819
if (!this.isRemote && !this.igxForOf[index]) {
822820
continue;
823821
}
824-
825-
const oldVal = this.individualSizeCache[index] || 0;
826-
const newVal = h + this.getMargin(rNode, dimension);
822+
const margin = this.getMargin(rNode, dimension);
823+
const oldVal = this.individualSizeCache[index];
824+
const newVal = (dimension === 'height' ? h : rNode.clientWidth) + margin;
827825
this.individualSizeCache[index] = newVal;
828826
const currDiff = newVal - oldVal;
829827
diffs.push(currDiff);
830828
totalDiff += currDiff;
831-
832-
this.sizesCache[index + 1] = this.sizesCache[index] + newVal;
829+
this.sizesCache[index + 1] = (this.sizesCache[index] || 0) + newVal;
833830
}
834831
}
832+
// update cache
833+
if (Math.abs(totalDiff) > 0) {
834+
for (let j = this.state.startIndex + this.state.chunkSize + 1; j < this.sizesCache.length; j++) {
835+
this.sizesCache[j] = (this.sizesCache[j] || 0) + totalDiff;
836+
}
835837

836-
for (let j = this.state.startIndex + this.state.chunkSize + 1; j < this.sizesCache.length; j++) {
837-
this.sizesCache[j] += totalDiff;
838-
}
839-
840-
const oldScrollSize = this.scrollComponent.size;
841-
this.scrollComponent.size = this._calcSize();
842-
843-
if (this.scrollComponent.size !== oldScrollSize) {
844-
this._zone.run(() => {
845-
this.scrollbarVisibilityChanged.emit();
846-
this.contentSizeChange.emit();
847-
});
848-
}
838+
// update scrBar heights/widths
839+
const reducer = (acc, val) => acc + val;
849840

850-
if (Math.abs(totalDiff) > 0) {
851-
this._adjustScrollPositionAfterSizeChange(totalDiff);
841+
const hSum = this.individualSizeCache.reduce(reducer);
842+
if (hSum > this._maxSize) {
843+
this._virtRatio = hSum / this._maxSize;
844+
}
845+
this.scrollComponent.size = Math.min(this.scrollComponent.size + totalDiff, this._maxSize);
846+
this._virtSize = hSum;
847+
if (!this.scrollComponent.destroyed) {
848+
this.scrollComponent.cdr.detectChanges();
849+
}
850+
const scrToBottom = this._isScrolledToBottom && !this.dc.instance.notVirtual;
851+
if (scrToBottom && !this._isAtBottomIndex) {
852+
const containerSize = parseInt(this.igxForContainerSize, 10);
853+
const maxVirtScrollTop = this._virtSize - containerSize;
854+
this._bScrollInternal = true;
855+
this._virtScrollPosition = maxVirtScrollTop;
856+
this.scrollPosition = maxVirtScrollTop;
857+
return;
858+
}
859+
if (this._adjustToIndex) {
860+
// in case scrolled to specific index where after scroll heights are changed
861+
// need to adjust the offsets so that item is last in view.
862+
const updatesToIndex = this._adjustToIndex - this.state.startIndex + 1;
863+
const sumDiffs = diffs.slice(0, updatesToIndex).reduce(reducer);
864+
if (sumDiffs !== 0) {
865+
this.addScroll(sumDiffs);
866+
}
867+
this._adjustToIndex = null;
868+
}
852869
}
853870
}
854871

projects/igniteui-angular/src/lib/grids/grid/grid.master-detail.spec.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -590,13 +590,14 @@ describe('IgxGrid Master Detail #grid', () => {
590590
setupGridScrollDetection(fix, grid);
591591
const targetCellElement = grid.gridAPI.get_cell_by_index(0, 'ContactName');
592592
UIInteractions.simulateClickAndSelectEvent(targetCellElement);
593+
await wait(DEBOUNCETIME);
593594
fix.detectChanges();
594595

595596
UIInteractions.triggerEventHandlerKeyDown('End', gridContent, false, false, true);
596-
await wait(DEBOUNCETIME);
597597
fix.detectChanges();
598598
await wait(DEBOUNCETIME);
599599
fix.detectChanges();
600+
await wait(DEBOUNCETIME);
600601

601602
const lastRow = grid.gridAPI.get_row_by_index(52);
602603
expect(lastRow).not.toBeUndefined();

projects/igniteui-angular/src/lib/grids/hierarchical-grid/hierarchical-grid.navigation.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -645,23 +645,23 @@ describe('IgxHierarchicalGrid Navigation', () => {
645645
// eslint-disable-next-line @typescript-eslint/no-shadow
646646
const hierarchicalGrid = fixture.componentInstance.hierarchicalGrid;
647647
fixture.detectChanges();
648-
await wait();
648+
await wait(DEBOUNCE_TIME);
649649

650650
hierarchicalGrid.filter('Artist', 'd', IgxStringFilteringOperand.instance().condition('contains'));
651651
fixture.detectChanges();
652-
await wait();
652+
await wait(DEBOUNCE_TIME);
653653

654654
hierarchicalGrid.expandRow(6);
655655
fixture.detectChanges();
656-
await wait();
656+
await wait(DEBOUNCE_TIME);
657657

658658
hierarchicalGrid.verticalScrollContainer.getScroll().scrollTop = 2000;
659659
fixture.detectChanges();
660660
await wait(DEBOUNCE_TIME);
661661

662662
hierarchicalGrid.clearFilter();
663663
fixture.detectChanges();
664-
await wait();
664+
await wait(DEBOUNCE_TIME);
665665

666666
hierarchicalGrid.verticalScrollContainer.getScroll().scrollTop = 2000;
667667
fixture.detectChanges();

0 commit comments

Comments
 (0)