【发布时间】:2021-09-17 12:41:28
【问题描述】:
我目前正在使用 Angular 12 处理 PrimeNG 12 表的项目,但我在 Angular 的更改检测和表更新方面遇到了一些问题,特别是试图阻止 PrimeNG p-table 滚动回数据刷新置顶。
在某些背景下,我有一个服务(我们称之为LocationService),它负责保存位置列表并每隔(例如,500 毫秒)更新一次。类似于以下内容:
location.ts
interface Location {
id: string;
lat: number;
lng: number
}
location.service.ts
// RxJS Behaviour Subjects
_locationUpdates$: BehaviorSubject<Location[]> = new BehaviorSubject<Location[]>([]);
// RxJS Observables
locationUpdates$: Observable<Location[]> = _locationUpdates.asObservable();
// Service Function
startUpdates() {
// Called within a service
timer(0, 500).subscribe(() => {
this._locations.forEach(location => {
location.lat = // ... some method to calculate new latitude
location.lng = // ... some method to calculate new longitude
});
this._locationUpdates$.next(this._locations);
});
}
现在,我有一个组件可以订阅位置更新并将它们显示为 p-table 中的 (Lat, Lng),但还要求经度在 -45.0 到 45.0 度之间(其他组件可能没有有这个要求)。滚动顺序无关紧要,尽管大多数情况下它的顺序相同,因为行并没有太大变化。
我目前正在订阅它,使用虚拟滚动,因为可能有数百个潜在的行:
location-component.html
<ng-container *ngIf="locations$ | async as locations">
<p-table
dataKey="id"
scrollHeight="flex"
[rows]="100"
[scrollable]="true"
[value]="locations"
[virtualScroll]="true"
[virtualRowHeight]="34"
>
<ng-template pTemplate="header">
<tr>
<th>Latitude</th>
<th>Longitude</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-location>
<tr>
<td>{{ location.lat }}</td>
<td>{{ location.lng }}</td>
</tr>
</ng-template>
</p-table>
</ng-container>
location-component.ts
// RxJS observables
locations$: Observable<Location[]>;
// Constructor
constructor(private _locationService: LocationService) {
locations$ = _locationService.locationUpdates$
.pipe(
map(locations => locations.filter(location => location.lng >= -45.0 && location.lng <= 45.0))
)
}
这里的问题是,当我运行代码时,每次刷新数据时表格都会对齐到顶部。我认为这是由于数组引用发生了变化。但是,如果我离开 async 管道并使用本地数组,只需在更新时修改它,如下所示:
.subscribe(locations => {
this._locations.splice(0, this._locations.length, ...locations.filter(location => location.lng >= -45.0 && location.lng <= 45.0));
this._changeDetectorRef.detectChanges();
}
Angular 没有检测到更改,即使他调用了detectChanges()(它似乎什么也没做)。使用this._locations = this._locations.slice() 之类的东西以另一种方式通知它只会让我回到上面的问题。
我的问题是这样的:有人对我如何解决这个问题有任何建议吗?我的目标是每 X 毫秒刷新一次数据,但也允许用户在更新时滚动。
任何帮助将不胜感激!
【问题讨论】:
标签: javascript angular typescript datatable primeng