From 357d6366b426c0c2a0f5b3e667f61aa2aec1ab68 Mon Sep 17 00:00:00 2001 From: mertsincan Date: Fri, 5 Jan 2024 01:08:04 +0000 Subject: [PATCH] Fixed #14488 - Table Virtual Scroll with Fixed Columns and Lazy Loading Causes Erratic Scrolling and Incomplete Data Display --- src/app/components/scroller/scroller.ts | 22 +++++++++---------- src/app/components/table/table.ts | 29 ++++++++++--------------- 2 files changed, 23 insertions(+), 28 deletions(-) diff --git a/src/app/components/scroller/scroller.ts b/src/app/components/scroller/scroller.ts index a1f80ca1f8d..ec1b33bcb18 100644 --- a/src/app/components/scroller/scroller.ts +++ b/src/app/components/scroller/scroller.ts @@ -504,10 +504,6 @@ export class Scroller implements OnInit, AfterContentInit, AfterViewChecked, OnD return this._columns; } - get isPageChanged() { - return this._step ? this.page !== this.getPageByFirst() : true; - } - constructor(@Inject(DOCUMENT) private document: Document, @Inject(PLATFORM_ID) private platformId: any, private renderer: Renderer2, private cd: ChangeDetectorRef, private zone: NgZone) {} ngOnInit() { @@ -653,8 +649,12 @@ export class Scroller implements OnInit, AfterContentInit, AfterViewChecked, OnD return this.elementViewChild; } - getPageByFirst() { - return Math.floor((this.first + this.d_numToleratedItems * 4) / (this._step || 1)); + getPageByFirst(first?: any) { + return Math.floor(((first ?? this.first) + this.d_numToleratedItems * 4) / (this._step || 1)); + } + + isPageChanged(first?: any) { + return this._step ? this.page !== this.getPageByFirst(first ?? this.first) : true; } scrollTo(options: ScrollToOptions) { @@ -977,10 +977,10 @@ export class Scroller implements OnInit, AfterContentInit, AfterViewChecked, OnD this.handleEvents('onScrollIndexChange', newState); - if (this._lazy && this.isPageChanged) { + if (this._lazy && this.isPageChanged(first)) { const lazyLoadState = { - first: this._step ? Math.min(this.getPageByFirst() * this._step, (this.items).length - this._step) : first, - last: Math.min(this._step ? (this.getPageByFirst() + 1) * this._step : last, (this.items).length) + first: this._step ? Math.min(this.getPageByFirst(first) * this._step, (this.items).length - this._step) : first, + last: Math.min(this._step ? (this.getPageByFirst(first) + 1) * this._step : last, (this.items).length) }; const isLazyStateChanged = this.lazyLoadState.first !== lazyLoadState.first || this.lazyLoadState.last !== lazyLoadState.last; @@ -993,14 +993,14 @@ export class Scroller implements OnInit, AfterContentInit, AfterViewChecked, OnD onContainerScroll(event: Event) { this.handleEvents('onScroll', { originalEvent: event }); - if (this._delay && this.isPageChanged) { + if (this._delay && this.isPageChanged()) { if (this.scrollTimeout) { clearTimeout(this.scrollTimeout); } if (!this.d_loading && this.showLoader) { const { isRangeChanged } = this.onScrollPositionChange(event); - const changed = isRangeChanged || (this._step ? this.isPageChanged : false); + const changed = isRangeChanged || (this._step ? this.isPageChanged() : false); if (changed) { this.d_loading = true; diff --git a/src/app/components/table/table.ts b/src/app/components/table/table.ts index d6929fe08a6..2ede18e55d5 100644 --- a/src/app/components/table/table.ts +++ b/src/app/components/table/table.ts @@ -1,16 +1,13 @@ import { animate, AnimationEvent, style, transition, trigger } from '@angular/animations'; import { CommonModule, DOCUMENT, isPlatformBrowser } from '@angular/common'; import { - AfterContentChecked, AfterContentInit, - AfterViewChecked, AfterViewInit, ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChildren, Directive, - DoCheck, ElementRef, EventEmitter, HostListener, @@ -33,28 +30,29 @@ import { ViewEncapsulation } from '@angular/core'; import { FormsModule } from '@angular/forms'; -import { BlockableUI, FilterMatchMode, FilterMetadata, FilterOperator, FilterService, LazyLoadMeta, OverlayService, PrimeNGConfig, PrimeTemplate, SelectItem, SharedModule, SortMeta, TableState, TranslationKeys } from 'primeng/api'; +import { BlockableUI, FilterMatchMode, FilterMetadata, FilterOperator, FilterService, LazyLoadMeta, OverlayService, PrimeNGConfig, PrimeTemplate, ScrollerOptions, SelectItem, SharedModule, SortMeta, TableState, TranslationKeys } from 'primeng/api'; import { ButtonModule } from 'primeng/button'; import { CalendarModule } from 'primeng/calendar'; import { ConnectedOverlayScrollHandler, DomHandler } from 'primeng/dom'; import { DropdownModule } from 'primeng/dropdown'; -import { InputNumberModule } from 'primeng/inputnumber'; -import { InputTextModule } from 'primeng/inputtext'; -import { PaginatorModule } from 'primeng/paginator'; -import { Scroller, ScrollerModule } from 'primeng/scroller'; -import { ScrollerOptions } from 'primeng/api'; -import { SelectButtonModule } from 'primeng/selectbutton'; -import { TriStateCheckboxModule } from 'primeng/tristatecheckbox'; -import { ObjectUtils, UniqueComponentId, ZIndexUtils } from 'primeng/utils'; -import { Subject, Subscription } from 'rxjs'; import { ArrowDownIcon } from 'primeng/icons/arrowdown'; import { ArrowUpIcon } from 'primeng/icons/arrowup'; import { CheckIcon } from 'primeng/icons/check'; import { FilterIcon } from 'primeng/icons/filter'; +import { FilterSlashIcon } from 'primeng/icons/filterslash'; import { SortAltIcon } from 'primeng/icons/sortalt'; import { SortAmountDownIcon } from 'primeng/icons/sortamountdown'; import { SortAmountUpAltIcon } from 'primeng/icons/sortamountupalt'; import { SpinnerIcon } from 'primeng/icons/spinner'; +import { InputNumberModule } from 'primeng/inputnumber'; +import { InputTextModule } from 'primeng/inputtext'; +import { PaginatorModule } from 'primeng/paginator'; +import { Scroller, ScrollerModule } from 'primeng/scroller'; +import { SelectButtonModule } from 'primeng/selectbutton'; +import { TriStateCheckboxModule } from 'primeng/tristatecheckbox'; +import { Nullable, VoidListener } from 'primeng/ts-helpers'; +import { ObjectUtils, UniqueComponentId, ZIndexUtils } from 'primeng/utils'; +import { Subject, Subscription } from 'rxjs'; import { ExportCSVOptions, TableColResizeEvent, @@ -74,9 +72,6 @@ import { TableRowUnSelectEvent, TableSelectAllChangeEvent } from './table.interface'; -import { Nullable, VoidListener } from 'primeng/ts-helpers'; -import { FilterSlashIcon } from 'primeng/icons/filterslash'; -import { platformBrowser } from '@angular/platform-browser'; @Injectable() export class TableService { @@ -3268,7 +3263,7 @@ export class FrozenColumn implements AfterViewInit { set frozen(val: boolean) { this._frozen = val; - this.updateStickyPosition(); + Promise.resolve(null).then(() => this.updateStickyPosition()); } @Input() alignFrozen: string = 'left';