Я работал над виртуальной прокруткой с дизайном материала angular8 +.У нас есть страница поиска, и мы получаем тысячи результатов поиска на основе критериев поиска.Эти результаты отображаются в матричной таблице с помощью cdk-virtual-scroll-viewport.
В первый раз результатов поиска виртуальная прокрутка работает, как и ожидалось.Но во второй раз, если я изменяю результаты поиска и выполняю прокрутку вверх / вниз, поведение будет непоследовательным.
import { DataSource } from '@angular/cdk/collections';
import { BehaviorSubject, Observable } from 'rxjs';
const PAGESIZE = 50;
const ROW_HEIGHT = 48;
export class GridTableDataSource extends DataSource<any> {
private _data: any[];
get allData(): any[] {
return this._data.slice();
}
set allData(data: any[]) {
this._data = data;
this.viewport.scrollToOffset(0);
this.viewport.setTotalContentSize(this.itemSize * data.length);
this.visibleData.next(this._data.slice(0, PAGESIZE));
}
offset = 0;
offsetChange = new BehaviorSubject(0);
constructor(initialData: any[], private viewport: CdkVirtualScrollViewport, private itemSize: number) {
super();
this._data = initialData;
this.viewport.elementScrolled().subscribe((ev: any) => {
const start = Math.floor(ev.currentTarget.scrollTop / ROW_HEIGHT);
const prevExtraData = start > 5 ? 5 : 0;
// const prevExtraData = 0;
const slicedData = this._data.slice(start - prevExtraData, start + (PAGESIZE - prevExtraData));
this.offset = ROW_HEIGHT * (start - prevExtraData);
this.viewport.setRenderedContentOffset(this.offset);
this.offsetChange.next(this.offset)
this.visibleData.next(slicedData);
});
}
private readonly visibleData: BehaviorSubject<any[]> = new BehaviorSubject([]);
connect(collectionViewer: import('@angular/cdk/collections').CollectionViewer): Observable<any[] | ReadonlyArray<any>> {
return this.visibleData;
}
disconnect(collectionViewer: import('@angular/cdk/collections').CollectionViewer): void {
}
}
export class CustomVirtualScrollStrategy extends FixedSizeVirtualScrollStrategy {
constructor() {
super(ROW_HEIGHT, 1000, 2000);
}
attach(viewport: CdkVirtualScrollViewport): void {
this.onDataLengthChanged();
}
}
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [{provide: VIRTUAL_SCROLL_STRATEGY, useClass: CustomVirtualScrollStrategy}],
})
export class AppComponent implements OnInit {
placeholderHeight = 0;
displayedColumns: string[] = ['id', 'name', 'age'];
dataSource: GridTableDataSource;
rows = [];
itemSize = 48;
@ViewChild(CdkVirtualScrollViewport) viewport: CdkVirtualScrollViewport;
constructor() {
}
ngOnInit() {
console.log(this.rows);
}
getDetails(){
this.rows = [];
this.rows = Array(4422).fill(0).map((x, i) => {
return {name: 'name' + i, id: i, age: 27};
});
this.dataSource = new GridTableDataSource(this.rows, this.viewport, this.itemSize);
this.dataSource.offsetChange.subscribe(offset => {
console.log(offset);
this.placeholderHeight = offset
console.log(this.placeholderHeight);
})
this.dataSource.allData = this.rows;
this.dataSource.disconnect;
}
placeholderWhen(index: number, _: any) {
return index == 0;
}
}
Виртуальная прокрутка должна работать, как и ожидалось, для каждого результата поиска.Но он работает нормально только в первый раз.