问题描述
我正在尝试将 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 是截图。正如您在右下角看到的,数据被提取但没有被处理到表格中。
有人可以帮忙解决这个问题吗?
解决方法
正如错误所说,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
运算符设置 data
、paginator
和 sort
属性并使用 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,100]"></mat-paginator>
</ng-container>
编辑:在 res
运算符中将 dataSource
更改为 map
您可以尝试像这样删除管道“异步”:
[dataSource]="dataSource"
如 official documentation 中所述,您可以使用带有 observable 或 promise 的异步管道。但是在您的情况下,您的数据源本身不是可观察的或承诺。您的 getList 方法是可观察的。因此,您无法在尝试时对数据源使用异步管道。