angular - 为什么在使用带有 *ngIf 内容切换的异步管道时,Ionic (Angular) 中的可观察对象会发送新的服务请求?
问题描述
我正在创建一个屏幕,该屏幕使用段组件来过滤使用来自 http 请求的异步管道的 observable 列表中的结果。我将为此创建一个管道过滤器来清理它,因为它是多余的,但我更担心它为什么会这样发生——我是 observables 的新手。一切都按预期显示和工作,但是当我切换屏幕顶部的段过滤器时,它每次都会向 api 发送一个新请求,并根据客户类型重建列表。是因为 *ngIf 是基于客户的 type 属性吗?每次切换时发送一个新请求似乎有点荒谬。此外,如果您可以建议使用过滤器(或任何方法)更好的方法来做到这一点,我们将不胜感激。
我的服务类中的方法:
/**
* Get a list of the user's customers
*/
list(): Observable<Customer[]> {
return this.authHttp.get<Customer[]>('/api/customers')
.map(customers => {
return customers.json().data
}).pipe(
catchError(this.handleError('getCustomers', []))
);
}
我的控制器中的方法:
ionViewDidLoad() {
this.customers = this.customerService.list();
}
具有模型绑定的分段组件:
<ion-segment [(ngModel)]="type">
<ion-segment-button value="prospect">
Prospects
</ion-segment-button>
<ion-segment-button value="customer">
Customers
</ion-segment-button>
</ion-segment>
内容切换和异步管道:
<div [ngSwitch]="type">
<ion-list *ngSwitchCase="'prospect'">
<ng-container *ngFor="let customer of customers | async">
<button *ngIf="customer.type==='prospect'" ion-item (click)="customerSelected(customer)">
{{ customer.first_name }} {{ customer.last_name }}
</button>
</ng-container>
</ion-list>
<ion-list *ngSwitchCase="'customer'">
<ng-container *ngFor="let customer of customers | async">
<button ion-item *ngIf="customer.type==='customer'" (click)="customerSelected(customer)">
{{ customer.first_name }} {{ customer.last_name }}
</button>
</ng-container>
</ion-list>
</div>
解决方案
因为 NgSwitch 正在删除 dom 元素。因此,当您切换开关并将异步管道添加到 dom 时,它会在您的 observable 上调用 .subscribe() ,这意味着它将重新调用您的 API。
来自 Angular 文档: https ://angular.io/api/common/NgSwitch#ngSwitch
NgSwitch
匹配 switch 表达式。当嵌套匹配表达式时添加/删除 DOM 子树
您可以设置结果而不是直接绑定到 observable。
ionViewDidLoad() {
this.customerService.list().subscribe(customers => {
this.customers = customers;
});
}
然后从 *ngFor 中删除异步管道。
<ng-container *ngFor="let customer of customers">
或者不使用 ngSwitch,使用 [hidden] 属性。
<ion-list [hidden]="type !== 'prospect'">
<ng-container *ngFor="let customer of customers | async">
<button *ngIf="customer.type==='prospect'" ion-item (click)="customerSelected(customer)">
{{ customer.first_name }} {{ customer.last_name }}
</button>
</ng-container>
</ion-list>
<ion-list [hidden]="type !== 'customer'">
<ng-container *ngFor="let customer of customers | async">
<button ion-item *ngIf="customer.type==='customer'" (click)="customerSelected(customer)">
{{ customer.first_name }} {{ customer.last_name }}
</button>
</ng-container>
</ion-list>
[隐藏] 虽然有一些警告......
推荐阅读
- c# - 如何从库代码中使用 Microsoft.Extensions.Logging?
- android - Android Room - 插入密封类列表..或任何东西
- excel - 使用联合的 VBA 图表宏范围 - 错误
- python - 为多个脚本构建 docker 映像
- android - 需要帮助了解 Expo 中的音频
- python - 如何从 .bat 运行 python 代码(而不是 python 脚本)
- sql - 如何使用 GROUP BY 修改 SQL SELECT 请求
- flutter - 某些字符未正确加载
- open-policy-agent - OPA HTTP 自引用 PUT 请求超时
- google-sheets - 我可以将富文本添加到谷歌表格注释吗?