我已经编码了两个可观察对象:
一个用于提交表单提交事件的事件:
<form role="form" (ngSubmit)="search()">
...
</form>
到达search()
并发出:
private search(): void {
this.searchClickSubject.next();
}
在组件构造函数中:
private searchClickSubject:Subject<void>;
private searchClick$:Observable<any>;
constructor() {
this.searchClickSubject = new Subject<void>();
this.searchClick$ = this.searchClickSubject.asObservable();
}
如您所见,我在Observable
上使用searchClickSubject
方法从主题searchClickSubject.asObservable
创建了一个searchClick$
。
从现在开始,我正在使用此searchClick$
来观察submit form
。
在那之后,我创建了另一个Observable:
this.searchQuery$ = this.searchClick$.pipe(
map(() => <Query>{
offset: 0,
limit: 10
})
);
因此,每次发出Query
时,我都会使用自定义的可传递函数发出requestm:
this.metrics$ = this.searchQuery$
.pipe(
pageLoading(),
makeRequest(),
loadedPage()
);
这是我的ngOnInit()
:
public ngOnInit() {
// Grab search button click event
this.searchQuery$ = this.searchClick$.pipe(
map(() => <Query>{
offset: 0,
limit: 10
})
);
this.metrics$ = this.searchQuery$
.pipe(
//...
);
}
但是,请求启动了两次。
我使用async
管道创建订阅:
<div class="row" *ngIf="!(metrics$ | async)" style="margin: 1.54em;">
<div *ngIf="metrics$ | async; let metric;"...
有什么想法吗?
答案 0 :(得分:2)
您两次订阅了可观察的metrics$
。这是发生了什么:
*ngIf="!(metrics$ | async)"
进行订阅。*ngIf="metrics$ | async; let metric;"
进行订阅。使用share()
中的metrics$
运算符可以防止在新订阅上重新发出请求。如果您想更深入地了解此主题,请查看此great article。
答案 1 :(得分:1)
您已经订阅了metrics$
两次,您可以使用as
语法来代替它,如下所示:
<div *ngIf="metrics$ | async as metric; else loading">
<!-- Statements when metrics data found -->
</div>
<ng-template #loading>
<!-- Loading stuff... -->
<div class="row" style="margin: 1.54em;">
</ng-template>
有关更多详细信息,请参见Handling observables with NgIf & Async Pipe。