如何解决Angular Material Table替换动态数据的初始化报错问题
错误原因
类成员的初始化执行顺序为:先执行类属性声明处的初始化逻辑,再执行constructor构造函数内的赋值逻辑。你当前在类属性声明阶段就使用this.columnsData初始化dataSource,但columnsData的赋值操作是在constructor中才执行的,此时columnsData还未完成初始化,因此触发该报错。
修复方案
两种可行修改方式按需选择即可:
方式1:直接在类属性声明处初始化columnsData
直接给columnsData赋初始空数组,不需要放到constructor中赋值,就能在类属性阶段直接引用:
export class ColumnSearchComponent implements OnInit{ displayedColumns: string[] = ['select', 'columnName', 'columnType', 'tableName', 'schemaName']; selection = new SelectionModel<IClusterColumnOrient>(true, []); @ViewChild('searchInput', { static: true }) searchInput: ElementRef; // 声明时直接初始化空数组 columnsData: IClusterColumnOrient[] = [] isSearching: boolean = false columns: string[] // 此时this.columnsData已经完成初始化,不会报错 dataSource = new MatTableDataSource<IClusterColumnOrient>(this.columnsData); constructor(private httpClient: HttpClient){ // 移除这里的columnsData、isSearching赋值逻辑即可 } // 其他逻辑不变 }
方式2:将dataSource的初始化挪到constructor中
如果不想修改columnsData的赋值位置,只需要把dataSource的初始化放到constructor里,保证columnsData赋值完成后再初始化dataSource:
export class ColumnSearchComponent implements OnInit{ displayedColumns: string[] = ['select', 'columnName', 'columnType', 'tableName', 'schemaName']; selection = new SelectionModel<IClusterColumnOrient>(true, []); @ViewChild('searchInput', { static: true }) searchInput: ElementRef; columnsData: IClusterColumnOrient[] isSearching: boolean columns: string[] // 只声明不初始化 dataSource: MatTableDataSource<IClusterColumnOrient>; constructor(private httpClient: HttpClient){ this.isSearching = false this.columnsData = [] // columnsData赋值完成后再初始化dataSource this.dataSource = new MatTableDataSource<IClusterColumnOrient>(this.columnsData); } // 其他逻辑不变 }
动态数据更新逻辑
后续接口请求拿到返回数据后,不需要重新实例化MatTableDataSource,直接修改dataSource.data属性即可自动刷新表格:
ngOnInit(){ fromEvent(this.searchInput.nativeElement, 'keyup').pipe( map((event: KeyboardEvent) => (event.target as HTMLInputElement).value.trim()), debounceTime(700), distinctUntilChanged(), // 可选:添加空值过滤,避免无意义的接口请求 filter(keyword => keyword.length > 0), switchMap(keyword => { this.isSearching = true; // 替换为你的实际后端接口请求逻辑 return this.httpClient.get<IClusterColumnOrient[]>('/api/column/search', { params: { keyword } }) }) ).subscribe({ next: (res) => { this.isSearching = false; // 直接更新数据源即可触发表格刷新 this.dataSource.data = res; }, error: () => { this.isSearching = false; this.dataSource.data = []; } }) }
内容的提问来源于stack exchange,提问作者Kristoffer Tølbøll
相关产品推荐
相关产品推荐

