我正在尝试使用 CDK 虚拟滚动为项目列表实现无限循环滚动
我到了放弃的地步。我做不到,我怎样才能实现这个 CDK 虚拟滚动?
这是我的代码
import { Component, ViewChild, ChangeDetectionStrategy } from '@angular/core';
import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
import { Observable, BehaviorSubject } from 'rxjs';
import { map } from 'rxjs/operators';
@Component({
selector: 'my-app',
template: `
<ng-container *ngIf="infinite | async; let items">
<cdk-virtual-scroll-viewport itemSize="50"
(scrolledIndexChange)="nextBatch($event, (items[items.length - 1].index))">
<div *cdkVirtualFor="let item of items; trackBy: trackByIdx">{{item}}</div>
</cdk-virtual-scroll-viewport>
</ng-container>
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class AppComponent {
arr = Array.from({ length: 10 }).map((_, i) => `Item #${i}`);
offset = new BehaviorSubject<any>({ offset: 0 });
infinite: Observable<any[]>;
@ViewChild(CdkVirtualScrollViewport) viewPort: CdkVirtualScrollViewport;
constructor() {
this.infinite = this.offset.pipe(
map((n: any) => this.getBatch(n)),
);
}
getBatch({ offset, loadPrev, loadNext, e }) {
let arr = [...this.arr];
if (loadPrev) {
const last = arr[arr.length - 1];
return [last, ...arr];
}
if (loadNext) {
const first = arr[0];
return [...arr, first];
}
return arr;
}
nextBatch(e, offset) {
const end = this.viewPort.getRenderedRange().end;
const start = this.viewPort.getRenderedRange().start;
const total = this.viewPort.getDataLength();
if (start === 0) {
this.offset.next({ offset: offset, loadPrev: true, e });
}
if (end === total) {
this.offset.next({ offset: offset, loadNext: true, e });
}
}
trackByIdx(i) {
return i;
}
}
最佳答案
我们只需要检查滚动条是否滚动到最后一项,然后再滚动回第一项。例如:
app.component.html
<cdk-virtual-scroll-viewport class="example-viewport" [itemSize]="itemSize" (scrolledIndexChange)="onScroll($event)">
<div *cdkVirtualFor="let item of items" class="example-item">{{item}}</div>
</cdk-virtual-scroll-viewport>
应用程序组件.ts
items = Array.from({ length: 100 }).map((_, i) => `Item #${i}`);
itemSize = 5;
@ViewChild(CdkVirtualScrollViewport) viewPort: CdkVirtualScrollViewport;
onScroll(event) {
console.log(event);
if( event >= ((this.items.length-this.itemSize-1)*10) ) {
this.viewPort.scrollToIndex(0);
}
}
关于Angular CDK 虚拟滚动无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53143204/