我在组件mat-table
中使用MatTableDataSource
,我想从其父组件设置数据,但数据不会在屏幕上刷新,而子组件则检测到数据更改。
子组件
@Component({
selector: 'app-person-list',
template: `
<mat-table #table [dataSource]="dataSource">
<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef> Name </mat-header-cell>
<mat-cell *matCellDef="let person">{{ person.name }}</mat-cell>
</ng-container>
<ng-container matColumnDef="age">
<mat-header-cell *matHeaderCellDef> Age </mat-header-cell>
<mat-cell *matCellDef="let person">{{ person.age }}</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
`
})
export class PersonListComponent implements OnInit, OnChanges {
@Input() data: Person[];
displayedColumns = ['name', 'age'];
dataSource = new MatTableDataSource<Person>();
ngOnInit() {
this.dataSource.data = this.data;
}
ngOnChanges(changes) {
console.log('Data changed', this.data);
}
}
父组件
@Component({
selector: 'app',
template: `<app-person-list [data]="personList"></app-person-list>`
})
export class AppComponent implements OnInit {
personList: Person[] = [];
constructor(private service: PersonService) {
}
ngOnInit() {
this.service.getPersonList().subscribe(res => this.personList.push(...res));
}
}
有人知道数据更改时表格未更新的原因吗?提前谢谢!
答案 0 :(得分:3)
问题是你只在ngOnInit上调用this.dataSource.data = this.data;
,这意味着你没有对更新的数据做任何事情。
我为此创建了一个管道,因此我不必在任何地方使用MatTableDataSource -
@Pipe({
name: 'dataSource'
})
export class DataSourcePipe implements PipeTransform {
transform(array: any[]): any {
return array ? new MatTableDataSource(array) : new MatTableDataSource([]);
}
}
在模板中使用它$data | dataSource
这样您的数据始终是最新的,您不必手动使用MatTableDataSource。
编辑: 使用此功能时,您仍然可以使用过滤器和排序功能。
您正在为组件提供数据,然后使用MatTableDataSource来包装它。相反,你可以这样做 - <component [data]="$array | async | dataSource"></component>
其中$ array是一个可观察的。
然后在组件内部 - <mat-table [dataSource]="data"></mat-table>
这样您就可以操作数据对象,而无需将其包装在组件内的MatTableDataSource中。
答案 1 :(得分:2)
我发现的唯一方法是更改数组的引用并重新分配...
子组件
@Component( [...] )
export class PersonListComponent implements OnChanges {
@Input() data: Person[];
displayedColumns = ['name', 'age'];
dataSource = new MatTableDataSource<Person>();
ngOnChanges(changes) {
this.dataSource.data = this.data;
}
}
父组件
@Component( [...] )
export class AppComponent implements OnInit {
personList: Person[] = [];
constructor(private service: PersonService) {
}
ngOnInit() {
this.service.getPersonList().subscribe(res => {
if (this.personList.length > 0) {
res.unshift(this.personList);
}
this.personList = res;
});
}
}