首页 > 解决方案 > 使用异步管道时缓存发出的值以便能够过滤掉未来的发出

问题描述

我正在尝试缓存 observable 的发射值,以过滤掉不相关的未来发射。

我有一条路线:

{ 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出现空值。我想避免使用水龙头操作符缓存它,而只是想出一个干净的替代方案,就像我试图走的路一样。我错过了什么?

标签: angularrxjsbehaviorsubject

解决方案


要仅将值与最后一次发射进行比较,您可以使用 RxJSpluck运算符选择id属性并使用distinctUntilChanged运算符忽略通知,直到id更改。

尝试以下

ngOnInit() {
    this.user$ = this.route.params.pipe(
       pluck('id'),
       distinctUntilChanged(),
       switchMap(id => {
         return this.http.getUser(id)
       })
    );
}

或者要忽略所有重复项并仅针对不同id的 s 触发 HTTP 请求,您可以使用 RxJSdistinct运算符。

ngOnInit() {
    this.user$ = this.route.params.pipe(
       distinct(params => params['id']),
       switchMap(params => {
         return this.http.getUser(params.id)
       })
    );
}

推荐阅读