FormArray值为空但含FormControls,MatDataTable自定义DataSource.connect异常
解决FormArray值为空但包含FormControls的MatDataTable数据源问题
我懂你现在的困扰——FormArray明明装着FormControls,但它的value却是空的,而且自定义的DimensionDataSource里结合分页器处理数据时还出了问题。咱们一步步拆解解决:
先排查FormArray value为空的核心原因
先搞清楚这个空值是不是表象问题:
- 检查子FormControl的初始值:如果创建FormControl时没设初始值(比如用
new FormControl()而非new FormControl('默认值')),那FormArray的value自然会是全空数组,哪怕控件本身存在。 - 确认FormArray实例是否正确:有没有可能你操作的FormArray和绑定给DataSource的不是同一个?可以在DataSource的constructor里加个
console.log(this._dimensions.controls),看看控件数量和预期一致不。
修复DataSource.connect()的分页逻辑问题
你提到合并Observable处理分页切片,大概率是没正确监听FormArray的控件变化,或者只监听了valueChanges但没覆盖控件数量变化的场景(比如新增/删除FormControl)。这里给你调整后的完整实现:
import { DataSource } from '@angular/cdk/collections'; import { FormArray } from '@angular/forms'; import { MatPaginator } from '@angular/material/paginator'; import { Observable, combineLatest, map, tap } from 'rxjs'; export class DimensionDataSource extends DataSource<any> { constructor( private _dimensions: FormArray, private _paginator: MatPaginator, ) { super(); } connect(): Observable<any[]> { // 合并两个关键流:FormArray的数值变化 + 分页器的分页配置变化 return combineLatest([ // 监听valueChanges的同时,直接从控件列表取最新值,避免FormArray的value异常 this._dimensions.valueChanges.pipe( map(() => this._dimensions.controls.map(ctrl => ctrl.value)) ), this._paginator.page ]).pipe( // 调试用:可以打开看每次触发的原始数据和分页事件 // tap(([allData, pageEvt]) => console.log('当前全量数据:', allData, '分页参数:', pageEvt)), map(([allData, pageEvent]) => { // 计算分页切片的起始/结束索引 const startIdx = pageEvent.pageIndex * pageEvent.pageSize; return allData.slice(startIdx, startIdx + pageEvent.pageSize); }) ); } disconnect(): void { // 可在这里清理订阅,避免内存泄漏 } }
关键调整点:
- 用
combineLatest监听多流:同时响应FormArray的数值变化和分页器的分页操作,确保任何一个变动都能触发数据更新。 - 直接从控件取数值:绕过FormArray的
value可能出现的异常,直接遍历controls数组取每个控件的value,保证数据准确性。 - 严谨的分页切片逻辑:根据分页器的页码和每页数量计算切片范围,避免越界。
额外调试建议
- 打开代码里注释的
tap操作符,打印每次触发的全量数据和分页事件,确认数据是否符合预期。 - 确保组件里正确绑定分页器:
模板里也要正确关联:ngAfterViewInit() { this.dataSource.paginator = this.paginator; }<mat-paginator [pageSizeOptions]="[5, 10, 20]" showFirstLastButtons></mat-paginator>
这样调整后,应该能解决FormArray值为空但控件存在的问题,同时让分页逻辑正常运转。
内容的提问来源于stack exchange,提问作者doovers
相关产品推荐
相关产品推荐

