Angular 9 子组件如何刷新来自父组件的@Input数据?
解决方案
方案1:@Output事件触发父组件刷新(最推荐)
这是Angular官方推荐的父子组件通信方式,完全符合单向数据流规范,父子组件无业务耦合,子组件复用性不受影响。
- 子组件内定义输出事件,编辑操作成功后触发
import { Output, EventEmitter } from '@angular/core'; export class ChildTableComponent { // 定义数据更新事件 @Output() dataUpdated = new EventEmitter<void>(); // 对话框编辑提交、数据存入数据库成功的回调里触发事件 onEditComplete() { this.dataUpdated.emit(); } }
- 父组件监听子组件的事件,触发后重新拉取数据
父组件模板:
<!-- 绑定子组件的dataUpdated事件到刷新方法 --> <app-child-table [tableData]="tableList" (dataUpdated)="loadTableData()"></app-child-table>
父组件逻辑:
export class ParentComponent { tableList = []; loadTableData() { this.yourDataService.fetchTableList().subscribe(res => { // 必须生成新的数组引用,否则@Input变更检测不会触发 this.tableList = [...res]; }) } }
注意:给父组件的tableList赋值时不要直接修改原数组的元素,Angular默认对@Input的变更检测是浅比较,只有引用发生变化才会触发子组件的输入更新。如果已经确认@Input拿到最新数据但mat-table仍未刷新,可以在子组件的
ngOnChanges生命周期手动触发表格渲染:
import { ViewChild, OnChanges, SimpleChanges } from '@angular/core'; import { MatTable } from '@angular/material/table'; import { MatTableDataSource } from '@angular/material/table'; export class ChildTableComponent implements OnChanges { @Input() tableData: any[]; @ViewChild(MatTable) private table: MatTable<any>; dataSource = new MatTableDataSource(); ngOnChanges(changes: SimpleChanges) { if (changes['tableData']?.currentValue) { this.dataSource.data = changes['tableData'].currentValue; this.table?.renderRows(); } } }
方案2:共享服务托管全局状态(适合多组件共享数据场景)
如果这份表格数据会被多个组件使用,建议把数据状态托管到全局服务,基于RxJs实现数据自动广播,无需父子组件手动通信。
// 全局数据服务 import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; import { HttpClient } from '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class TableDataService { private tableDataSubject = new BehaviorSubject<any[]>([]); // 对外暴露可观察对象供组件订阅 tableData$ = this.tableDataSubject.asObservable(); constructor(private http: HttpClient) {} // 刷新全局数据 refreshTableData() { this.http.get<any[]>('/api/your-table-api').subscribe(res => { this.tableDataSubject.next([...res]); }) } }
父组件直接订阅服务的tableData$获取数据传给子组件,子组件编辑完成后直接调用服务的refreshTableData方法即可,所有订阅了该数据的组件都会自动拿到最新值,无需额外通信。
方案3:子组件直接调用数据服务(不推荐)
你提到的子组件直接调用父组件用的服务拉取数据的方案可以实现需求,但会导致子组件和业务逻辑强耦合,子组件的复用性会大幅降低,仅适合业务场景完全固定、不会复用该子组件的场景使用。
内容的提问来源于stack exchange,提问作者Elvis Shrestha
相关产品推荐
相关产品推荐

