首页 > 解决方案 > 更新 observable 中的值而不解析先前的运算符

问题描述

这是我想做的事情:我有一个来自异步数据源的用户列表。源返回一个Observable<User[]>. 然后该列表通过 Angular 的async管道显示在模板中,如下所示。

<ng-template #loading>Loading...</ng-template>
<ul *ngIf="users$ | async; let users; else loading">
  <li *ngFor="let user of users">{{user.name}}</li>
</ul>

用户列表是可搜索的。使用响应式表单,我已经像这样绑定了搜索字段的更改事件(this.resolve执行异步任务,具有签名(text: string) => Observable<User[]>):

search = new FormControl('');
users$ = this.search.valueChanges
  .pipe(startWith(this.search.value))
  .pipe(debounceTime(250))
  .pipe(distinctUntilChanged())
  .pipe(switchMap(this.resolve));

这工作得很好。当搜索输入发生变化时,搜索输入被去抖动,并触发一个新的异步请求来解析用户。

现在我有一个问题。用户可能在客户端发生变化,需要在列表中更新,而无需再次执行异步任务。我尝试在更新函数中使用另一个管道操作导致this.resolve再次执行。

update(user: User): void {
  this.users$ = this.users$
    .pipe(map(users => {
      // replace user in users
      return users;
    }));
}

但是,我不想再次解析用户。我只想在本地更新异步用户列表。我怎样才能做到这一点?

标签: javascriptangularrxjsobservable

解决方案


您可以使用Subject它并将其合并到之后的users$链中switchMap

otherUsers$ = new Subject();

users$ = this.search.valueChanges
  .pipe(
    startWith(this.search.value),
    debounceTime(250)),
    distinctUntilChanged()),
    switchMap(this.resolve),
    merge(otherUsers$),
  );

然后您可以调用next()并避免遍历整个链条:

otherUsers$.next([{}, {}, {}, ...]);

推荐阅读