使用可观察的过滤器过滤对象数组

时间:2019-01-23 22:34:25

标签: angular rxjs6

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

这是场景。我有users: User[]filter: FormControl和另一个数组filteredUsers: User[]。我想做的是根据filter中包含的值过滤用户列表。我能够弄清楚的唯一方法是使用tap,尽管这样做可行,但这似乎不是正确的方法...加上整个列表都被“过滤掉”,直到过滤器控件的第一个valueChange。

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

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

您是对的,水龙头不是“正确”的操作方式...正确的方法是在订阅中进行操作...

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更改检测。

答案 1 :(得分:0)

只需将点击功能移到订阅中:

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