使用 Observable 过滤器过滤对象数组

Filter an array of objects using an Observable filter

我正在努力寻找使用 RxJS 6 过滤对象数组的正确方法。

场景如下。我有 users: User[]filter: FormControl 和另一个数组 filteredUsers: User[]。我想做的是根据 filter 中包含的值过滤用户列表。我能够解决这个问题的唯一方法是使用 tap,虽然这有效,但它似乎不是正确的方法......而且整个列表是 "filtered out"直到过滤器控件有它的第一个 valueChange。

this.filter.valueChanges.pipe(
  tap((term) => {
    this.filteredUsers = this.users.filter(u => u.name.indexOf(term) != -1)
  })).subscribe()

如有任何帮助,我们将不胜感激。

你说得对,点击不是 "right" 的方法...正确的方法是在订阅中进行...

this.filter.valueChanges.pipe(startWith('')).subscribe(
  (term) => {
    this.filteredUsers = (term) ? this.users.filter(u => u.name.indexOf(term) != -1) : this.users;
});

并添加一个不过滤的空白支票,并以它开始流。完成和完成。不要在不需要的地方增加复杂性。 rxjs 建议在您的订阅函数中出现副作用,其他一切都应该是可转换的/功能性的,并且在控制器上设置一个值是一个副作用。

如果你想获得真正的反应,你可以加入一个异步管道作为很好的措施

this.filteredUsers$ = this.filter.valueChanges.pipe(startWith('')).tap(
  (term) => {
    return (term) ? this.users.filter(u => u.name.indexOf(term) != -1) : this.users;
});

然后在 HTML 而不是

*ngFor="let user of filteredUsers"

做:

*ngFor="let user of filteredUsers$ | async"

这里的好处是自动清理订阅和更好地支持 onpush 变化检测。

只需将点击功能移至订阅中即可:

this.filter.valueChanges.subscribe((term) => {
    this.filteredUsers = this.users.filter(u => u.name.indexOf(term) != -1)
  });