You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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[]类型的数据;同时数据是异步获取的,不能用同步方式直接初始化数据源。

修复步骤

  1. 调整组件逻辑,异步获取数据后初始化数据源
    在组件中先声明变量,再在数据获取完成的回调里初始化数据源:

    // 组件类中提前声明变量
    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);
            }
        )
    }
    
  2. 在组件初始化时触发数据获取
    在ngOnInit生命周期钩子中调用getProducts(),确保组件加载时启动数据请求:

    ngOnInit(): void {
        this.getProducts();
    }
    
  3. 更优方案:用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 14:41:04