【问题标题】:Error: InvalidPipeArgument: '[object Object]' for pipe 'AsyncPipe' MatTable Angular 11错误:InvalidPipeArgument:管道“AsyncPipe”MatTable Angular 11 的“[object Object]”
【发布时间】:2021-01-18 11:02:41
【问题描述】:

我正在尝试将 Angular MatTable 与异步管道一起使用。我从 RESTAPI 获取数据作为 Observable。但是,当我以这种方式使用 ([dataSource] = "dataSource | async") 时,我得到了上面提到的错误。

repository.service.ts:

public GetList(controller: string): Observable<T[]> {
return this.httpclient.get<T[]>(this.apiURL + '/' + controller + '/getList', { headers: this.headers });}

contact.component.ts:

ngOnInit() {
this.contactService.GetList("OfferContact").subscribe(res => {
  this.ContactList = res
  this.setFunctions(this.ContactList)
})} 
setFunctions(list) {
  this.dataSource.data = list;
  this.spinner.hide()
  this.dataSource.paginator = this.paginator;
  this.dataSource.sort = this.sort;
  }

contact.component.html:

           <table mat-table [dataSource]="dataSource|async" matSort>

                <ng-container matColumnDef="company">
                    <th mat-header-cell *matHeaderCellDef mat-sort-header> Firma Adı </th>
                    <td mat-cell *matCellDef="let element"> {{element.company}} </td>
                </ng-container>

                <ng-container matColumnDef="name">
                    <th mat-header-cell *matHeaderCellDef mat-sort-header> Yetkili Adı </th>
                    <td mat-cell *matCellDef="let element"> {{element.name}} </td>
                </ng-container> 
                   ...
                 </table>
            <mat-paginator [pageSizeOptions]="[20, 30, 50, 70, 100]"></mat-paginator>

错误

ERROR Error: InvalidPipeArgument: '[object Object]' for pipe 'AsyncPipe'

this 是截图。正如您在右下角看到的那样,数据已被提取但未处理到表中。

谁能帮忙解决这个问题?

【问题讨论】:

    标签: angular angular-material mat-table async-pipe


    【解决方案1】:

    正如错误所说,async 管道只能与可观察对象一起使用。您正在尝试使用 observable 的响应。

    选项 1:不带async 管道

    您可以简单地删除async 管道。当dataSource 变量为undefined 时,这可能会在组件初始化时在控制台中引发错误。

    <table mat-table [dataSource]="dataSource" matSort>
        <ng-container matColumnDef="company">
            <th mat-header-cell *matHeaderCellDef mat-sort-header> Firma Adı </th>
            <td mat-cell *matCellDef="let element"> {{element.company}} </td>
        </ng-container>
    
        <ng-container matColumnDef="name">
            <th mat-header-cell *matHeaderCellDef mat-sort-header> Yetkili Adı </th>
            <td mat-cell *matCellDef="let element"> {{element.name}} </td>
        </ng-container> 
            ...
    </table>
    <mat-paginator [pageSizeOptions]="[20, 30, 50, 70, 100]"></mat-paginator>
    

    选项 2:使用async 管道

    您可以将 HTTP 请求分配给控制器中的变量。然后您可以使用map 运算符来设置datapaginatorsort 属性,并使用finalize 运算符来隐藏微调器。

    试试下面的

    控制器

    dataSource$: Observable<any>;  // <-- define it as an observable ('$' at end is convention)
    ngOnInit() {
      this.dataSource$ = this.contactService.GetList("OfferContact").pipe(
        tap(res => {
          this.ContactList = res   // <-- is `this.ContactList` even required?
        }),
        map(dataSource => ({
          ...dataSource, 
          dataSource['data']: res,
          dataSource['paginator']: this.paginator,
          dataSource['sort']: this.sort
        })),
        finalize(() => this.spinner.hide())
      );
    }
    

    模板

    <ng-container *ngIf="(dataSource$ | async) as dataSource">   <!-- wrap it in *ngIf to reuse the response -->
        <table mat-table [dataSource]="dataSource" matSort>
            <ng-container matColumnDef="company">
                <th mat-header-cell *matHeaderCellDef mat-sort-header> Firma Adı </th>
                <td mat-cell *matCellDef="let element"> {{element.company}} </td>
            </ng-container>
    
            <ng-container matColumnDef="name">
                <th mat-header-cell *matHeaderCellDef mat-sort-header> Yetkili Adı </th>
                <td mat-cell *matCellDef="let element"> {{element.name}} </td>
            </ng-container> 
                ...
        </table>
        <mat-paginator [pageSizeOptions]="[20, 30, 50, 70, 100]"></mat-paginator>
    </ng-container>
    

    编辑:在 map 运算符中将 res 更改为 dataSource

    【讨论】:

    • 坦率地说,我不知道如何使用 map (...) 函数内部的操作。例如... dataSource, => Cannot find name 'dataSource'. Did you mean the instance member 'this.dataSource'? 给出警告。 dataSource.data: res, => An object literal cannot have multiple properties with the same name in strict mode. 发出警告。不知道... dataSource是缩写还是用法。
    • 那是我的错误。我将响应分配给变量res 而不是dataSource。我已经更新了答案。此外,我用括号表示法替换了点表示法,以避免 TS Linter 潜在的undefined 错误。请重试解决方案。
    • 感谢您和 Akif 的努力。它没有用。我将使用第一个解决方案
    【解决方案2】:

    您可以尝试像这样删除管道“异步”:

     [dataSource]="dataSource"
    

    正如official documentation 中提到的,您可以使用带有可观察或承诺的异步管道。但是在您的情况下,您的数据源本身不是可观察的或承诺。您的 getList 方法是可观察的。因此,您不能像尝试那样对数据源使用异步管道。

    【讨论】:

    • 我知道这种用法。但是当我使用它时,加载页面需要 10-15 秒。所以我想使用异步管道。它立即加载,但不加载数据行
    • 我编辑了答案。 @Michael D 对您的要求有很好的解释。
    猜你喜欢
    • 2018-05-23
    • 1970-01-01
    • 2017-12-05
    • 2018-06-22
    • 2018-05-11
    • 2019-01-03
    • 2021-01-02
    • 2018-03-18
    相关资源
    最近更新 更多