创建和侦听具有动态有效负载的HTTP可观察的正确方式



场景

用户有一个菜单,可以创建一组汽车标准,用于过滤结果服务器端。当用户单击"加载"按钮时,它会发送条件集以获得正确的结果,然后将其传递给子组件以进行显示。

我试图通过创建一个可观察的来正确地做到这一点,虽然它有效,但它闻起来不对劲。

父HTML

<h3>Select Criteria</h3>
<div>
<!-- Bunch of dropdowns and radio buttons and gizmos that form the filter menu omitted for brevity-->
</div>
<button (click)="loadCars()">Load Cars</button>
<child-comp-table [dataSet]="results$ | async"><child-comp-table>

父TS

var _results$ = new BehaviorSubject<any[]>([]);
readonly results$ = this._results$.asObservable();
loadCars() {
// construct payload based on selected criteria and store in postPayload variable
this.http.post(url, postPayload).subscribe((res:any) => {
this._results$.next(res.data);
});
}

这是正确的设置方式吗?我担心的是,我必须订阅,而不是使用现有的管道。

this.http.post(url, postPayload)返回一个Observable,所以我不明白你为什么订阅它,并且"保持";行为主体内部的结果。

我会选择以下方向:

let results$ = of([]); // init the obs with an observable containing empty list
loadCars() {
this.results$ = this.http.post(url, postPayload);
}

顺便说一句,我也会取消对它自己服务的HTTP调用,但是另一回事

在类似的情况下,我倾向于使用以下

  • 具有服务类,例如carService,其中";调用http";逻辑保持
  • carService公开了一个API方法,可以调用该方法来触发调用(例如loadcars(postPayload)(
  • carService还公开了一个Observable(例如loadCarsResult$(作为API,并且任何想要得到调用结果通知的人都必须订阅loadCarsResult$

carService的实现与您开发的非常相似,只是提取到一个单独的服务中,比如这个

@Injectable({
providedIn: 'root',
})
export class carService {
private _results$ = new BehaviorSubject<any[]>([]);
public results$ = this._results$.asObservable();
loadCars(postPayload) {
// pass the _result$ Subject to the subscribe method, which ensures that
// next, error and complete are correctly invoked
this.http.post(url, postPayload).subscribe(this._results$);
}
}

通过这种方式,您创建了一个";多播";机械装置换句话说,许多组件可以将subscriberesult$Observable,并且一旦http调用的结果到达,所有组件都将被更新。

另一种看待相同问题的方法是认为您已经将http调用的调用与返回结果的消耗分开。

相关内容

最新更新