为什么在使用带有*ngIf内容切换的异步管道时,Ionic(Angular)中的observables会发送新的服务请求?
我正在创建一个屏幕,该屏幕使用一个段组件来过滤http请求中使用异步管道的可观察对象列表中的结果。我将为它创建一个管道过滤器来清理它,因为它是多余的,但我更关心的是为什么它会以它的方式发生-我对可观察事物是新的。一切都按预期显示和工作,但当我切换屏幕顶部的分段过滤器时,它每次都会向api发送一个新请求,并根据客户类型重新构建列表。是因为*ngIf基于客户的type属性吗?每次它切换时发送一个新请求似乎有点可笑。此外,如果你能建议一个更好的方法来做这个过滤器(或任何方法),它将非常感谢 我的服务类中的方法:为什么在使用带有*ngIf内容切换的异步管道时,Ionic(Angular)中的observables会发送新的服务请求?,angular,ionic-framework,rxjs,observable,reactive-programming,Angular,Ionic Framework,Rxjs,Observable,Reactive Programming,我正在创建一个屏幕,该屏幕使用一个段组件来过滤http请求中使用异步管道的可观察对象列表中的结果。我将为它创建一个管道过滤器来清理它,因为它是多余的,但我更关心的是为什么它会以它的方式发生-我对可观察事物是新的。一切都按预期显示和工作,但当我切换屏幕顶部的分段过滤器时,它每次都会向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', []))
);
}
具有模型绑定的段组件:
<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>
{{customer.first_name}{{customer.last_name}}
{{customer.first_name}{{customer.last_name}}
因为NgSwitch正在删除dom元素。因此,当您切换开关并将异步管道添加到它在observable上调用的dom中时,这意味着它将重新调用您的API
来自角度文档:
NgSwitch
匹配开关表达式。当嵌套匹配表达式时,添加/删除DOM子树
您可以设置结果,而不是直接绑定到可观察对象
ionViewDidLoad() {
this.customerService.list().subscribe(customers => {
this.customers = customers;
});
}
然后从*ngFor中删除异步管道
<ng-container *ngFor="let customer of customers">
或不要使用ngSwitch,请使用[隐藏]属性
<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>
{{customer.first_name}{{customer.last_name}}
{{customer.first_name}{{customer.last_name}}
[隐藏]有一些警告
感谢您的精彩解释!这很有道理。我想我看得太多的是可观察的一面,而不是显而易见的一面欢迎!:)老实说,也许有一些非常聪明的方法可以利用可观测数据来实现这一点。有这么多的运营商,其中一些做一些非常酷的事情!在这种情况下,越简单越好。您当然可以将结果缓存在服务中,并让服务管理调用API(如果需要)(仍然总是返回可观察的结果)。不过,该解决方案本身也有很多问题,比如处理陈旧数据。
<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>