基于ng-zorro table滚动无限加载
首先复制一下ng-zorro的虚拟表格
这里选用虚拟表格,原因是数据页面有多个表格存在加载的数据量很大,且表格滚动时有事件监听不用写额外的方法去监听滚动条滚动
先打印分析表格滚动时有哪些信息被输出


从打印的信息内发现有个_renderedRange属性名为渲染的范围,因此可以通过该属性的end值来判断当前表格已经滚动到底部,因此我们先获取下_renderedRange的end值
但是打印时发现_renderedRange为私有属性无法直接获取

这里我们先用//@ts-ignore忽略下语法检查

滚动到底部正常打印100(当前只有100条数据)

但用//@ts-ignore这种方法是不可取的,因此我们点进cdkVirtualScrollViewport看看有没有方法返回了_renderedRange的值



因为angular内部源码基本都是面向对象的编程,因此可以尝试搜索下getrenderedRang

因此_renderedRange值可以通过getRenderedRange()方法来获取end值


正常获取end值 ,此时可以通过判断end值是否等于当前数据集合长度来加载数据

效果


优化下在表格最下方加入加载的标志提醒用户在加载

效果

当然还有后端已经查不到数据了,给用户相应的提示或者去控制不用在查询接口了剩下就自己优化啦
下面是实现的代码
<nz-table #virtualTable [nzBordered]="true" [nzVirtualItemSize]="54" [nzData]="listOfData" [nzVirtualForTrackBy]="trackByIndex" [nzFrontPagination]="false" [nzShowPagination]="false" [nzScroll]="{ x: '1200px', y: '240px' }" > <thead> <tr> <th nzLeft>Full Name</th> <th nzLeft>Age</th> <th>Index</th> <th>Column 1</th> <th>Column 2</th> <th>Column 3</th> <th>Column 4</th> <th>Column 5</th> <th>Column 6</th> <th>Column 7</th> <th>Column 8</th> <th nzRight>Action</th> </tr> </thead> <tbody> <ng-template nz-virtual-scroll let-data let-index="index"> <tr> <td nzLeft>{{ data.name }}</td> <td nzLeft>{{ data.age }}</td> <td>{{ data.index }}</td> <td>{{ data.address }}</td> <td>{{ data.address }}</td> <td>{{ data.address }}</td> <td>{{ data.address }}</td> <td>{{ data.address }}</td> <td>{{ data.address }}</td> <td>{{ data.address }}</td> <td>{{ data.address }}</td> <td nzRight> <a>action</a> </td> </tr> <tr> <td colSpan="12" *ngIf="index == listOfData.length - 1"> <nz-spin></nz-spin> </td> </tr> </ng-template> </tbody> </nz-table>
import { ChangeDetectionStrategy, Component, ViewChild } from '@angular/core';
import { NzTableComponent } from 'ng-zorro-antd/table';
import { Subject, takeUntil } from 'rxjs';
@Component({
selector: 'app-bottom-add-table-real',
templateUrl: './bottom-add-table-real.component.html',
styleUrls: ['./bottom-add-table-real.component.less'],
})
export class BottomAddTableRealComponent {
@ViewChild('virtualTable', { static: false })
nzTableComponent?: NzTableComponent<any>;
private destroy$ = new Subject<boolean>();
listOfData: any[] = [];
scrollToIndex(index: number): void {
this.nzTableComponent?.cdkVirtualScrollViewport?.scrollToIndex(index);
}
trackByIndex(_: number, data: any): number {
return data.index;
}
ngOnInit(): void {
const data = [];
for (let i = 0; i < 100; i++) {
data.push({
index: i,
name: `Edward`,
age: i,
address: `London`,
});
}
this.listOfData = data;
}
ngAfterViewInit(): void {
this.nzTableComponent?.cdkVirtualScrollViewport?.scrolledIndexChange
.pipe(takeUntil(this.destroy$))
.subscribe(() => {
const end =
this.nzTableComponent?.cdkVirtualScrollViewport?.getRenderedRange()
.end;
if (end === this.listOfData.length) {
this.getData();
}
});
}
timer: any = null;
getData() {
if (!this.timer) {
this.timer = setTimeout(() => {
const data = [];
for (let i = 0; i < 100; i++) {
data.push({
index: i,
name: `Edward`,
age: i,
address: `London`,
});
}
this.listOfData = [...this.listOfData, ...data];
clearTimeout(this.timer);
this.timer = null;
}, 2000);
}
}
ngOnDestroy(): void {
this.destroy$.next(true);
this.destroy$.complete();
}
}

浙公网安备 33010602011771号