该技能用于在 Angular 中虚拟化 TanStack Table 的最终行或列模型,需在正确的注入与响应式生命周期内完成。它建立在 @tanstack/table-core 的核心、入门与表格状态能力之上。虚拟化是对最终 Table 模型的渲染层处理,而不是一个功能插件。
用途
用于在 Angular 表格中实现行或列的虚拟化渲染,以应对大量数据下的性能问题。虚拟化作用于 Table 的最终模型,因此不会绕过表格自身的筛选、排序、展开、分组与分页逻辑。
主要能力
- 通过 computed 派生响应式模型,例如 computed(() => table.getRowModel().rows) 与 computed(() => table.getVisibleLeafColumns())。
- 通过 injectVirtualizer 创建虚拟器,其初始化函数会追踪信号读取,并要求处于注入上下文。
- 可配置 count、scrollElement、estimateSize、getItemKey、overscan 等参数。
- 支持行虚拟化与列虚拟化,以及测量与无限加载模式。
使用方式
在组件中声明滚动元素引用与响应式行模型,然后注入虚拟器。示例:
import { computed, viewChild } from '@angular/core' import { injectVirtualizer } from '@tanstack/angular-virtual' import type { ElementRef } from '@angular/core'
export class VirtualTable { readonly scrollElement = viewChild<ElementRef>('scrollElement') readonly rows = computed(() => this.table.getRowModel().rows) readonly rowVirtualizer = injectVirtualizer(() => ({ count: this.rows().length, scrollElement: this.scrollElement()?.nativeElement, estimateSize: () => 34, getItemKey: (index) => this.rows()[index]!.id, overscan: 5, })) readonly virtualRows = computed(() => this.rowVirtualizer.getVirtualItems()) readonly totalSize = computed(() => this.rowVirtualizer.getTotalSize()) }
核心模式
派生响应式模型:使用 computed(() => table.getRowModel().rows) 和 computed(() => table.getVisibleLeafColumns())。injectVirtualizer 会在其初始化函数中追踪信号读取,并且需要注入上下文。
自行负责布局契约:为滚动元素设置受限溢出,创建总尺寸占位元素,并对每个虚拟项进行位移或测量。动态行或列使用 grid/flex 宽度,并让粘性表头保持在正确的滚动几何中。
对无限获取进行门控:当最后一个虚拟项接近已获取长度时,仅在服务器仍有更多行且当前没有进行中的请求时才发起获取。手动排序需要服务器已排序的分页以及重置/重新获取策略。
常见错误
严重:在注入上下文之外构造。错误写法:
export function virtualize(options) { return injectVirtualizer(() => options) }
正确写法:
export class VirtualTable { readonly virtualizer = injectVirtualizer(() => options()) }
Angular 虚拟器与 injectTable 一样遵循依赖注入生命周期规则。
高:虚拟化原始数据。错误写法:
readonly rows = computed(() => this.data())
正确写法:
readonly rows = computed(() => this.table.getRowModel().rows)
原始数据会绕过 Table 的筛选、排序、展开、分组与分页。
高:忘记占位元素与位移变换。错误写法:
@for (item of virtualRows(); track item.key) { <div>{{ rows()[item.index].id }}</div> }
正确写法:
<div [style.height.px]="totalSize()" style="position:relative"> <div style="position:absolute"></div> </div>
虚拟化只计算范围与尺寸,不会应用 DOM 几何、粘性 CSS 或列宽。
API 发现
可查看已安装的 @tanstack/angular-table/dist/types/、已安装的 @tanstack/angular-virtual/dist/,以及维护中的 Angular 示例,以了解当前的行、列、测量与无限模式。
适用场景
适用于需要在 Angular 中渲染大量表格行或列、并希望保留 TanStack Table 筛选、排序、分组、分页等能力的场景。
限制
虚拟化不负责 DOM 几何、粘性 CSS 或列宽,这些需要开发者自行实现。虚拟器必须在注入上下文中构造。不能直接虚拟化原始数据,否则会绕过表格的筛选、排序、展开、分组与分页。无限加载需要服务器支持已排序分页,并需自行实现重置/重新获取策略。