Angular中PrimeNG表格懒加载致排序、筛选、分页失效求助
问题:PrimeNG表格启用懒加载后排序、筛选、分页功能失效
为PrimeNG表格实现懒加载后,排序、筛选、分页功能全部失效;移除懒加载配置后,这些功能可正常工作。以下是相关代码:
HTML代码
<p-table #dt [value]="lazy" [columns]="cols" [scrollable]="true" [tableStyle]="{ 'min-width': '50rem' }" scrollHeight="flex" [globalFilterFields]="['time','temperature','humidity','wind', 'pressure', 'direction', 'precipitation', 'rain', 'cloudcover','soilTemperature']" [rows]="10" [paginator]="true" [lazy]="true" (onLazyLoad)="loadData($event)" [loading]="loading" > <ng-template pTemplate="caption"> <div *ngIf="filterSwitch" class="flex"> <button pButton label="Clear" class="p-button-outlined" icon="pi pi-filter-slash" (click)="clearFilters(dt)"> </button> <span > <i class="pi pi-search"></i> <input class="filter-input" pInputText type="text" (input)="dt.filterGlobal($event.target.value, 'contains')" /> </span> </div> </ng-template> <ng-template pTemplate="header" let-columns> <tr class="icons"> <th style="min-width:250px" [pSortableColumn]="col.field" *ngFor="let col of columns"> <fa-icon [icon]="col.icon"></fa-icon> {{col.header}} <p-sortIcon [field]="col.field"></p-sortIcon> <p-columnFilter *ngIf="filterSwitch" [type]="col.type" display="menu" [field]="col.field"> </p-columnFilter> </th> </ng-template> <ng-template pTemplate="body" let-weather let-columns="columns"> <tr> <td *ngFor="let col of columns">{{ weather[col.field] + col.value }}</td> </tr> </ng-template> </p-table>
TypeScript代码
export class WeatherDataComponent implements OnInit, OnDestroy { @ViewChild('dt') table: Table; showError: string; weatherData: WeatherDataItem[] = []; private componentDestroyed$: Subject<boolean> = new Subject(); weatherDataLoading: boolean; icons: IconDefinition[] = [ faClock, faTemperatureHigh, faPercent, faWind, faGem, faDirections, faWater, faCloud, ]; cols: WeatherDataCol[]; loading: boolean = false; lazy: any; constructor( private weatherService: WeatherService, public datePipe: DatePipe ) { this.cols = [ new WeatherDataCol('time', 'Time', 'text', '', this.icons[0]), new WeatherDataCol( 'temperature', 'Temperature', 'text', '°C', this.icons[1] ), new WeatherDataCol('humidity', 'Humidity', 'numeric', '%', this.icons[2]), new WeatherDataCol('wind', 'Wind Speed', 'text', ' km/h', this.icons[3]), new WeatherDataCol( 'pressure', 'Air Pressure', 'text', ' hPa', this.icons[4] ), new WeatherDataCol( 'direction', 'Wind Direction', 'numeric', '°', this.icons[5] ), new WeatherDataCol( 'precipitation', 'Precipitation', 'numeric', 'mm', this.icons[6] ), new WeatherDataCol('rain', 'Rain', 'numeric', 'mm', this.icons[6]), new WeatherDataCol( 'cloudcover', 'Cloudcover', 'numeric', 'mm', this.icons[7] ), new WeatherDataCol( 'soilTemperature', 'Soil Temperature', 'text', '°C', this.icons[1] ), ]; } ngOnInit(): void { this.weatherDataLoading = true; this.weatherService .getWeatherData() .pipe( finalize(() => (this.weatherDataLoading = false)), takeUntil(this.componentDestroyed$) ) .subscribe({ next: (historicalWeatherData) => { const temperatures = historicalWeatherData.hourly.temperature_2m; const times = historicalWeatherData.hourly.time.map((time) => this.datePipe.transform(time, 'shortTime') ); const humidities = historicalWeatherData.hourly.relativehumidity_2m; const windSpeeds = historicalWeatherData.hourly.windspeed_10m; const airPressures = historicalWeatherData.hourly.surface_pressure; const windDirections = historicalWeatherData.hourly.winddirection_10m; const precipitations = historicalWeatherData.hourly.precipitation; const rain = historicalWeatherData.hourly.rain; const cloudcover = historicalWeatherData.hourly.cloudcover; const soilTemperatures = historicalWeatherData.hourly.soil_temperature_0_to_7cm; temperatures.forEach((value, i) => { this.weatherData.push( new WeatherDataItem( value, times[i], humidities[i], windSpeeds[i], airPressures[i], windDirections[i], precipitations[i], rain[i], cloudcover[i], soilTemperatures[i] ) ); }); }, error: () => (this.showError = 'Something went wrong. Please try refreshing the page'), }); this.loading = true; } loadData(event: LazyLoadEvent) { this.loading = true; setTimeout(() => { if (this.weatherData) { this.lazy = this.weatherData.slice(event.first, event.first + event.rows); this.loading = false; console.log(this.weatherData); } }, 1000); } }
排查思路及修复方案
1. 未处理懒加载事件中的排序、筛选参数
PrimeNG懒加载模式下,表格不会自动处理排序和筛选逻辑,所有数据处理逻辑都需要在loadData方法中完成。当前代码仅处理了分页的first和rows参数,完全忽略了排序(sortField、sortOrder)、列筛选(filters)、全局筛选(globalFilter)参数,导致这些操作无效果。
修改loadData方法,加入排序、筛选处理:
// 先在组件中添加totalRecords属性 totalRecords: number = 0; loadData(event: LazyLoadEvent) { this.loading = true; setTimeout(() => { if (this.weatherData) { let filteredData = [...this.weatherData]; // 处理排序 if (event.sortField && event.sortOrder) { filteredData.sort((a, b) => { const valA = a[event.sortField]; const valB = b[event.sortField]; if (typeof valA === 'string') { return event.sortOrder * valA.localeCompare(valB); } return event.sortOrder * (valA - valB); }); } // 处理列筛选 if (event.filters) { Object.keys(event.filters).forEach(field => { const filter = event.filters[field]; if (filter.value) { filteredData = filteredData.filter(item => { const itemVal = String(item[field]).toLowerCase(); const filterVal = String(filter.value).toLowerCase(); switch (filter.matchMode) { case 'contains': return itemVal.includes(filterVal); case 'equals': return itemVal === filterVal; // 可根据需要扩展其他匹配模式 default: return true; } }); } }); } // 处理全局筛选 if (event.globalFilter) { const filterVal = event.globalFilter.toLowerCase(); filteredData = filteredData.filter(item => { return ['time','temperature','humidity','wind', 'pressure', 'direction', 'precipitation', 'rain', 'cloudcover','soilTemperature'].some(field => String(item[field]).toLowerCase().includes(filterVal) ); }); } // 更新分页数据和总条数 this.lazy = filteredData.slice(event.first, event.first + event.rows); this.totalRecords = filteredData.length; this.loading = false; } }, 1000); }
2. 缺少总数据量配置
懒加载模式下,表格需要知道数据总条数才能正确渲染分页控件。在p-table标签中添加[totalRecords]="totalRecords":
<p-table ... [totalRecords]="totalRecords" >
同时在数据加载完成后初始化总条数:
// 在ngOnInit的subscribe next回调中添加 this.totalRecords = this.weatherData.length;
3. 清空筛选后未重新加载数据
点击Clear按钮后,需要触发懒加载重新获取全量数据,否则页面会保留之前的筛选结果。修改clearFilters方法:
clearFilters(dt: Table) { dt.clear(); // 触发懒加载事件,传递默认参数 this.table.onLazyLoad.emit(this.table.createLazyLoadMetadata()); }
4. 验证懒加载事件参数
在loadData方法中打印event对象,确认排序、筛选参数是否正确传递:
loadData(event: LazyLoadEvent) { console.log('LazyLoadEvent:', event); // ... 其他逻辑 }
通过以上步骤,即可修复懒加载模式下排序、筛选、分页失效的问题。
内容的提问来源于stack exchange,提问作者mrtn4899
相关产品推荐
相关产品推荐

