Angular Material Table dataSource接收Observable报错类型不匹配,如何修复?
问题
我正在构建一个简易的Angular电商应用,希望用Angular Material Table展示通过服务获取的产品数据。
我定义了Product接口:
export interface Product { id: number; name: String; price: number; }
我的assets文件夹中有products.json文件。服务类中的getProducts()方法用于获取该JSON数据(未来可能对接远程后端):
private products_url = "/assets/data/products.json"; public getProducts(): Observable<Product[]> { //return this.http.get<Product[]>(`${this.apiServerUrl}/product/all`); return this.http.get<Product[]>(this.products_url); }
组件类中有getProducts()函数调用该服务:
public getProducts(): void { this.canteenService.getProducts().subscribe( (response: Product[]) => { this.products = response; }, (error: HttpErrorResponse) => { alert(error.message); } ) }
当我尝试通过该组件函数为Material Table声明dataSource时出现错误:
public dataToDisplay = this.getProducts();; public dataSource = new ExampleDataSource(this.dataToDisplay);
错误提示:Argument of type 'void' is not assignable to parameter of type 'Product[]'.ts(2345)
请问该如何修复这个问题?
解决方案
问题根源
组件的getProducts()方法返回值是void,直接赋值给dataToDisplay无法拿到Product[]类型的数据;同时数据是异步获取的,不能用同步方式直接初始化数据源。
修复步骤
调整组件逻辑,异步获取数据后初始化数据源
在组件中先声明变量,再在数据获取完成的回调里初始化数据源:// 组件类中提前声明变量 public products: Product[] = []; public dataSource!: ExampleDataSource; public getProducts(): void { this.canteenService.getProducts().subscribe( (response: Product[]) => { this.products = response; // 数据加载完成后再初始化数据源 this.dataSource = new ExampleDataSource(this.products); }, (error: HttpErrorResponse) => { alert(error.message); } ) }在组件初始化时触发数据获取
在ngOnInit生命周期钩子中调用getProducts(),确保组件加载时启动数据请求:ngOnInit(): void { this.getProducts(); }更优方案:用Observable配合异步管道(符合Angular异步风格)
如果使用Angular Material自带的MatTableDataSource,可以直接通过Observable和async管道简化逻辑,无需手动管理订阅:import { MatTableDataSource } from '@angular/material/table'; // 声明Observable类型的产品数据 public products$ = this.canteenService.getProducts(); // 或者直接初始化数据源 public dataSource = new MatTableDataSource<Product>(); ngOnInit(): void { // 方案一:手动订阅更新数据源 this.products$.subscribe( data => this.dataSource.data = data, error => alert(error.message) ); // 方案二:模板中使用async管道(无需手动订阅) // 模板代码示例:<table mat-table [dataSource]="products$ | async">...</table> }
内容的提问来源于stack exchange,提问作者Somo
相关产品推荐
相关产品推荐

