问题描述
我正在尝试缓存可观察对象的发射值,以过滤掉无关的未来发射。
我有一条路线:
{ path: "user/:id/:type",component: UserComponent }
在该组件中,我获得了ActivatedRoute
参数,switchMap
到实际的http调用,并在模板上使用了async
管道来显示用户详细信息。
user$: Observable<User>;
ngOnInit() {
this.user$ = this.route.params.pipe(
switchMap(params => {
return this.http.getUser(params.id)
})
);
}
模板本身:
<div *ngIf="user$ | async as user">
<span>{{ user.id }}</span>
<span>{{ user.name }}</span>
</div>
如果路线更改但this.route.params
参数保持不变,我想过滤掉:id
值。
我在想类似的东西
user$: Observable<User>;
ngOnInit() {
this.user$ = this.route.params.pipe(
withLatestFrom(this.user$ || Observable.from({})),filter( ([params,user]) => {
return (params.id !== user.id); // filter if params id equals to last fetched user
}),switchMap(params => {
return this.http.getUser(params.id)
})
);
}
但是withLatestFrom
变为空。
我想避免使用tap操作符对其进行缓存,而只想出一个干净的替代方法,例如我尝试过的路。我想念什么?
解决方法
要仅将值与最后一个发射进行比较,可以使用RxJS pluck
运算符选择id
属性,然后使用distinctUntilChanged
运算符忽略通知,直到id
改变了。
尝试以下
ngOnInit() {
this.user$ = this.route.params.pipe(
pluck('id'),distinctUntilChanged(),switchMap(id => {
return this.http.getUser(id)
})
);
}
或者忽略所有重复项并仅针对不同的id
触发HTTP请求,可以使用RxJS distinct
运算符。
ngOnInit() {
this.user$ = this.route.params.pipe(
distinct(params => params['id']),switchMap(params => {
return this.http.getUser(params.id)
})
);
}